Wiki

root/cobra/trunk/HowTo/700-XNA.cobra

Revision 2418, 6.1 KB (checked in by Chuck.Esterbrook, 21 months ago)

(minor) Added .skip. to XNA How-To as XNA is not commonly installed.
reported-by:hopscc

Line 
1# .skip. XNA is not commonly installed. other tests cover these features
2# .require. dotnet
3# .compile-only.
4"""
5xna.cobra
6
7This sample shows basic XNA use.
8
9XNA is Microsoft's .NET-based API for game programming on Windows, Xbox and other Microsoft devices.
10
11To use this sample:
12 * Download and install XNA Game Studio 3.1
13 * Correct the XNA paths below if needed.
14 * Run with: cobra 700-XNA.cobra
15 * Use the arrow keys to move the man.
16 * You can hold more than one arrow key down at a time.
17
18If you don't see a gingerbread man and a dog, or you get errors about urls or images, then adjust
19the `_getImages` method or supply your own man.png and dog.png.
20
21You can also run with "cobra -d ..." for debugging symbols and "cobra -turbo ..."
22for maximum speed (and minimum checks).
23
24You can search the web for more information about XNA.
25
26For a cross platform alternative see http://cobra-language.com/trac/cobra/wiki/SFMLFramework
27
28Credit: Kurper, CobraCommander
29"""
30
31# A typical directory for XNA follows. Correct if needed for your system.
32@args -lib:"C:\Program Files\Microsoft XNA\XNA Game Studio\v3.1\References\Windows\x86"
33
34# 64-bit Windows is a little different:
35@args -lib:"C:\Program Files (x86)\Microsoft XNA\XNA Game Studio\v3.1\References\Windows\x86"
36
37@ref 'Microsoft.Xna.Framework'
38@ref 'Microsoft.Xna.Framework.Game'
39@ref 'System.Drawing'
40
41@number float32
42
43use System.IO
44use System.Net
45use Microsoft.Xna.Framework
46use Microsoft.Xna.Framework.Graphics
47use Microsoft.Xna.Framework.Input
48
49
50class Sprite
51
52    var _texture as Texture2D
53    var _batch as SpriteBatch
54    var _pos as Vector2
55
56    cue init(texture as Texture2D, batch as SpriteBatch, pos as Vector2)
57        base.init
58        _texture, _batch, _pos = texture, batch, pos
59
60    def draw(sb as SpriteBatch)
61        """ Draw this sprite on the screen. """
62        sb.draw(_texture, _pos, Color.white)
63
64    get x as number
65        return _pos.x
66
67    get y as number
68        return _pos.y
69
70    def move(dx as number, dy as number)
71        """ Moves this sprite dx pixels to the right and dy pixels down. """
72        _pos.x += dx
73        _pos.y += dy
74
75
76class MyGame inherits Game
77
78    var _tick as uint
79    var _graphics as GraphicsDeviceManager
80    var _spriteBatch as SpriteBatch?
81    var _sprites as IList<of Sprite>
82
83    cue init
84        base.init
85        _graphics = GraphicsDeviceManager(this)
86        _sprites = List<of Sprite>()
87        _getImages
88
89    def _getImages
90        imgTools, maxWidth = ImageTools(), 128
91
92        url = 'http://icons.iconseeker.com/png/fullsize/the-real-christmas-05/gingerbread-man.png'
93        imgTools.fetchImage('man.png', url)
94        imgTools.constrainImageWidth('man.png', maxWidth)
95
96        url = 'http://www.capek9cardio.com/wp-content/uploads/2009/05/bad-dog.png'
97        imgTools.fetchImage('dog.png', url)
98        imgTools.constrainImageWidth('dog.png', maxWidth)
99
100    def loadContent is override, protected
101        _spriteBatch = SpriteBatch(_graphics.graphicsDevice)
102        # The canonical XNA way to do this is a content pipeline, but doing that
103        # without Visual Studio is a major pain. Instead, load from files directly.
104        # This is probably somewhat less efficient, but it shouldn't make a big
105        # difference unless you have a LOT of sprites.
106        man = Texture2D.fromFile(_graphics.graphicsDevice, 'man.png')
107        dog = Texture2D.fromFile(_graphics.graphicsDevice, 'dog.png')
108        # Create a few sprites at various positions.
109        _sprites.add(Sprite(man, _spriteBatch, Vector2(0, 0)))
110        _sprites.add(Sprite(dog, _spriteBatch, Vector2(man.width*2, 0)))
111
112    def unloadContent is override, protected
113        # If you have any unloading to do, I guess you should put it here.
114        # We don't, or at least we're blissfully unaware if we do.
115        pass
116
117    def update(gameTime as GameTime?) is override, protected
118        base.update(gameTime)
119        # Move the player's sprite depending on keyboard input.
120        # We just define the first thing in _sprites to be the player's
121        # and the second to be the dog.
122        # A real game would do something a bit more robust and organized.
123        assert _sprites.count
124        _tick += 1
125        player = _sprites[0]
126        keys = Keyboard.getState
127        if keys.isKeyDown(Keys.Left), player.move(-1, 0)
128        if keys.isKeyDown(Keys.Right), player.move(1, 0)
129        if keys.isKeyDown(Keys.Up), player.move(0, -1)
130        if keys.isKeyDown(Keys.Down), player.move(0, 1)
131        # dog
132        if _tick % 2 == 0
133            dog = _sprites[1]
134            if dog.x > player.x, dog.move(-1, 0)
135            else if dog.x < player.x, dog.move(1, 0)
136            if dog.y > player.y, dog.move(0, -1)
137            else if dog.y < player.y, dog.move(0, 1)
138
139    def draw(gameTime as GameTime?) is override, protected
140        _graphics.graphicsDevice.clear(Color.cornflowerBlue)
141        batch = _spriteBatch to !
142        batch.begin
143        for sprite in _sprites, sprite.draw(batch)
144        batch.end
145        base.draw(gameTime)
146
147    def main
148        .run
149
150
151class ImageTools
152    """
153    Fetches images from URLs and can size them down to a max constrained width.
154    Uses System.Net and System.Drawing to accomplish these.
155    """
156
157    def fetchImage(fileName as String, url as String)
158        if File.exists(fileName), return
159        print 'Fetching a [fileName] from the web...'
160        System.Net.WebClient().downloadFile(url, fileName)
161
162    def constrainImageWidth(fileName as String, width as int)
163        # A `use System.Drawing` above would expose two Color types, two Graphics types, etc.
164        # due to XNA having these things too. So instead this method uses fully qualified type names
165        # as this is the only place that needs System.Drawing.
166        bm = System.Drawing.Bitmap(fileName)
167        if bm.width <= width, return
168        height = ((width / bm.width) * bm.height) to int  # scale down height proportionately
169        newBM = System.Drawing.Bitmap(width, height)
170        using g = System.Drawing.Graphics.fromImage(newBM)
171            g.compositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality
172            g.smoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality
173            g.interpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic
174            g.drawImage(bm, System.Drawing.Rectangle(0, 0, width, height))
175        # avoid Windows file locks with a temp file, .dispose and .move:
176        tmpFileName = '-tmp-' + fileName
177        newBM.save(tmpFileName, System.Drawing.Imaging.ImageFormat.png)
178        newBM.dispose
179        bm.dispose
180        File.delete(fileName)
181        File.move(tmpFileName, fileName)
182
Note: See TracBrowser for help on using the browser.