Help creating more than one instance of an object?
BlitzMax Forums/BlitzMax Beginners Area/Help creating more than one instance of an object?
| ||
Ok, I think I'm getting confused about something and I hope when someone replys it'll be what I need to move forward.. I want to create more than one instance of a pre-defined object, like a small rectangle. For instance, say I want to create a starfield. Nothing fancy, just say 40 5x5 rectangles on the screen in random places but I don't want to make 40 drawrec commands with 40 sets of co-ordinates. Can someone give me an example of this? As basic as possable? I've seen it in a few tutorials but they all seem to gloss over what exactly they do, or they seem to be part of a bigger chunk of code, which I'm really having a great deal of trouble with. Either that or I'm missing it each and every time I look for it. Help me out guys, I'm going nuts over this!! Thanks! :) |
| ||
for f=1 to 40 rectangle.draw(int rnd(0.0,799.0),int rnd(0.0,639.0)) next |
| ||
Strict Const MAX_STARS=100 Const WIDTH = 800 Const HEIGHT = 600 Graphics WIDTH, HEIGHT ,0 Type TStar Field x Field y Field radius Field speed End Type Global StarList: TList = New TList 'make some stars For Local i = 1 To MAX_STARS Local s:TStar = New TStar s.x = Rand(0,WIDTH) s.y = Rand(0,HEIGHT) s.radius = Rand(1,4) s.Speed = Rand(1,5) StarList.AddLast(s) Next While Not KeyHit(KEY_ESCAPE) Cls 'Move and draw the stars For Local s:TStar = EachIn StarList s.x:+s.speed 'wrap around If s.x>=WIDTH Then s.x:-WIDTH DrawOval s.x, s.y, s.radius, s.radius Next Flip 1 Wend |
| ||
Ok Grey Alien, I think I sort of understand that, but what if I want to make a player shot? How would this translate into that? I appreciate the help, I hope to god this sinks in. I keep thinking one day I'll see something that makes everything else fall into place like a moment of clarity! Thanks again guys! |
| ||
A player shot should have its own type, and either has one instance with a TList (or similar) of shots, or a new instance for each shot |
| ||
That's what I'm getting at. I understand that much, I just have no idea how the code would be arranged. I tried to translate Grey Alien's code into a player shot, but I just get the one instance created. Here's what I did (please don't laugh, I'm crap!): Type TPlayer Field x:Int=200 Field y:Int=300 Field speed Function UpdateState() If KeyDown(key_left) Then player.x:-4 If KeyDown(key_right) Then player.x:+4 If KeyDown(key_up) Then player.y:-4 If KeyDown(key_down) Then player.y:+4 If player.x <0 Then player.x=0 If player.x >WIDTH-40 Then player.x=WIDTH-40 If player.y <0 Then player.y=0 If player.y >HEIGHT-20 Then player.y=HEIGHT-20 End Function End Type Type TShot Field x:Int=Player.x Field y:Int=Player.y Field rate Field speed Field radius End Type Global ShotList: TList = New TList Global Player:TPlayer = New TPlayer Global StarList: TList = New TList 'make some stars For Local i = 1 To MAX_STARS Local s:TStar = New TStar s.x = Rand(0,WIDTH) s.y = Rand(0,HEIGHT) s.radius = Rand(1,4) s.Speed = Rand(1,5) StarList.AddLast(s) Next 'make some shots For Local i = 1 To MAX_STARS Local sh:TShot = New TShot sh.radius = 4 sh.Speed = 5 ShotList.AddLast(sh) Next While Not KeyHit(KEY_ESCAPE) Cls 'Move and draw the stars DrawRect(Player.x,Player.y,40,20) Player.UpdateState() For Local s:TStar = EachIn StarList s.x:-s.speed 'wrap around If s.x<0 Then s.x=WIDTH DrawOval s.x, s.y, s.radius, s.radius Next If KeyDown(key_space) For Local sh:TShot = EachIn Shotlist sh.x:+sh.speed DrawRect sh.x,sh.y,sh.radius,sh.radius Next EndIf Flip 1 Wend I'm still (even after several months) very green to programming. I'm starting to wonder if my mind is capable of storing all I need to know. :( |
| ||
You have lots of shots, they just all have the same position. (Also it should be 0 to maxshots) Edit If you havent defined Maxstars you will only have one shot |
| ||
Max_Stars was defined by Grey Alien as 100 right at the top. I just used it since it was already defined. I could have just had any number in there. I realise there is only one shot with only one position, I need to know how I can rectify the problem and understand it! FYI, I'm brand new to coding in ANY language! |
| ||
Just to clarify, I need the shot to stay hanging around after I have released spacebar, create an additional shot every time I hit spacebar and cease to exist when it leaves the screen. Oh, it'd be useful if it came from the ship too rather than the ship's initial position ;-) And oh to have a laptop that didnt press buttons of it's own accord and have a trackpad that stops working for 30 secs every five minutes.. adding to my frustration slightly :-) |
| ||
Strict Const MAX_STARS=100 Const WIDTH = 800 Const HEIGHT = 600 Graphics WIDTH, HEIGHT ,0 Type TStar Field x Field y Field radius Field speed End Type Type TShot Field x Field y Field radius Field speed Function Create:TShot(x,y) Local s:TShot = New TSHot s.x = x s.y = y s.radius = 5 s.speed = 5 ShotList.AddLast(s) Return s End Function End Type Type TPlayer Field x:Int=200 Field y:Int=300 Field w = 40 Field h = 20 Field speed = 4 Field FireCounter = 0 Field FireSpeed = 10 Method UpdateState() If KeyDown(key_left) Then x:-speed If KeyDown(key_right) Then x:+speed If KeyDown(key_up) Then y:-speed If KeyDown(key_down) Then y:+speed If x < 0 Then x=0 If x > WIDTH-w Then x=WIDTH-w If y < 0 Then y=0 If y > HEIGHT-h Then y=HEIGHT-h End Method End Type Global StarList: TList = New TList Global ShotList: TList = New TList Global Player:TPlayer = New TPlayer 'make some stars For Local i = 1 To MAX_STARS Local s:TStar = New TStar s.x = Rand(0,WIDTH) s.y = Rand(0,HEIGHT) s.radius = Rand(1,4) s.Speed = Rand(1,5) StarList.AddLast(s) Next While Not KeyHit(KEY_ESCAPE) Cls 'Move and draw the stars SetColor 255,255,255 For Local s:TStar = EachIn StarList s.x:-s.speed 'wrap around If s.x<0 Then s.x:+WIDTH DrawOval s.x, s.y, s.radius, s.radius Next 'draw player on top of stars SetColor 0,200,255 DrawRect(Player.x,Player.y,Player.w, Player.h) Player.UpdateState() 'make new bullets? If KeyDown(KEY_SPACE) And Player.FireCounter = 0 Then TShot.Create(Player.X+Player.w, Player.Y+(Player.h/2)) 'Sset a counter going so the player can't fire again immediately. Player.FireCounter = Player.FireSpeed EndIf 'reduce firecounter, but only if active. If Player.FireCounter> 0 Then Player.FireCounter:-1 'move and draw the bullets SetColor 255,50,50 For Local s:TShot = EachIn ShotList s.x:+s.speed 'wrap around If s.x>=WIDTH Then ShotList.Remove(s) 'kill the bullet DrawOval s.x, s.y, s.radius, s.radius Next SetColor 255,255,255 'restore colour Flip 1 Wend Notes: - Shot has a Function to create new instances of itself and add to the ShotList. - Player.UpdateState is now a Method so you don't have to put player. in front of all the coordinates and I used a speed field. Methods are not the same as Functions, read up about them. - Beforehand you were creating a load of ready made shots, that's not the way to do it, you should have an empty list and add shots when fire is pressed, and delete them when they go off-screen. - See how have I limited the firespeed. - Player now has w (width) and h (height) fields. - Really the Press Space detection should go in UpdateState. Hope this helps, it was fun. |
| ||
Thanks for that, it did clear up most of my issues, one little thing though. I don't understand the relationship between the spacebar being pressed (TShot.Create) and the shot being drawn: If KeyDown(KEY_SPACE) And Player.FireCounter = 0 Then TShot.Create(Player.X+Player.w, Player.Y+(Player.h/2)) 'Sset a counter going so the player can't fire again immediately. Player.FireCounter = Player.FireSpeed EndIf 'move and draw the bullets SetColor 255,50,50 For Local s:TShot = EachIn ShotList s.x:+s.speed 'wrap around If s.x>=WIDTH Then ShotList.Remove(s) 'kill the bullet DrawOval s.x, s.y, s.radius, s.radius If they are in two separate If conditionals, how does the second part of code get involked? I'm going to read this over and over though untill it clicks. It's got to at some point.. right? :) Thanks again for the great help and glad it was fun! On a side note, has anyone had a look at the Sloan Kelly Beginners Guide Book? Is it any good? |
| ||
When space is pressed it creates a shot and adds it to the shotlist. But it's not drawn with that code it's just created *ready* to be drawn. The For loop simply loops through the list of shots (if any). when you start the game, the list is empty so nothing is drawn. When you create one or more shots, it loops through them, moves each one, checks to see if it's off screen and should be destroyed (That's what the If s for), and then draws it. Take another look, it's nice and simple. |
| ||
http://www.blitzbasic.com/Community/posts.php?topic=42519 |
| ||
Not sure about nice and simple for my.. simple mind! I think I get it now though, if I go over it enough it'll fall into place and hopefully stick in my head! Can't thank you enough GA, thanks mate! |
| ||
you are welcome, just keep on practicing, and remember - keep it simple. |