Spaceship with OOP
VERSION 1 of 2
Spaceship OOP
VERSION 2 of 2
VERSION 1 of 2
Strict ' 'strict' = must declare variables ' VARIABLES Global GW = 800 ' Graphics Height Global GH = 600 ' Graphics Width Global GD = 0 ' Graphics Depth "0" means Windowed Mode Global MID_GH = GH/2 ' Middle of the screen Height (Y) Global MID_GW = GW/2 ' Middle of the screen width (X) Global MX,MY ' Used for Mousex() and Mousey() Graphics(GW,GH,GD) Rem create an actor type that possess attributes that can be used by may different game characters. Player, enemy, Wizard, etc... The Type "ACTOR" is the beginning of our Object Oriented Programming (OOP) Actor is a Class or Type. It simply is a definition of what an "actor" is. the Fields can also called Attributes. for example, an actor has the x#,y# Fields that will hold the screen x,y coordinates that tell BMAX where to draw it. the actor class also has "Methods". Methods are functions that are unique to that class. the "update" method, for instance, will only work for the actor class. End Rem Type actor ' Field x# = GW/2 ' SCREEN X and Y POSITION (initially the middle) Field y# = GH/2 Field xint:Int ' x,y integers fot neater screen printing Field yint:Int Field color Field name:String ' string contains the text name of actor Field life = 100 ' life force (defaults to 100) Field entity ' a placeholder for the image of the actor ' Field angle# ' angle# = 0 to 360 degrees Field velocity# ' speed of the actor (forward momentum?) Field angular_velocity# ' rotational speed, i.e. how fast it spins Field friction# = 0.99 ' Friction slows down the actor slightly each frame Field rotfriction# = 0.97 ' slows down the rate of spin slightly each frame Method applyImpulse#(angular#,thrust#=0.0) ' add the rotational and/or thrust to the velocities ' these are taken from key inputs. see below angular_velocity# = angular_velocity# + angular# velocity# = velocity# + thrust# End Method Method update() rem This method calculates the velocity of the ship as well as the angle. It uses the SINE and COSINE of the current ANGLE to determine the direction the ship should travel. The ANGLE is between 0 and 360. both velocities (rotation and forward) are multiplied by a friction amount that will slow the ship down each frame End Rem angular_velocity# = angular_velocity# * rotfriction# velocity# = velocity# * friction ' move the ship forward x=x+(velocity*Cos(angle-90)) y=y+(velocity*Sin(angle-90)) ' Turn the ship angle#:+angular_velocity If angle#<0.0 Then angle#=360.0 If angle#>360.0 Then angle#= 0.00 ' If the actor goes off screen, WRAP to other side If x>GW Then x = 0 If x<0 Then x = GW If y<0 Then y = GH If y>GH Then y=0 End Method Method show() ' This Method is used to draw the current frame of the ship ' as well as the print the x,y and velocity values to the screen xint = x yint = y SetRotation(angle) ' turn spaceship to current angle SetColor 255,0,0 DrawImage(entity,x,y) SetTransform(0,1.1,1.1) SetColor 0,0,255 DrawRect x-44,y+30,96,15 SetScale 1,1 SetColor 255,255,0 DrawText "x="+xint+" y="+yint,x-40,y+32 DrawText "Velocity = "+velocity,x-40,y+48 End Method End Type Rem Now we create an extended Type called Player. Type Player will INHERIT all of the attributes and methods of actor, as well as add a new field of its own, inventory. the [] at the end indicate an array. inventory is an array of strings. End Rem Type player Extends actor Field inventory:String[] End Type Type enemy Extends actor Field anger End Type rem now create an INSTANCE of player called spaceship. End Rem Global spaceship:player = New player spaceship.name = "Bob" spaceship.entity = CreateImage(64,64,DYNAMICIMAGE) ' draw a spaceship 'AutoMidHandle(1) SetColor 255,255,0 SetLineWidth 3 DrawLine 0,64,32,0 DrawLine 32,0,64,64 DrawOval 24,16,16,16 GrabImage spaceship.entity,0,0 SetImageHandle(spaceship.entity,32,48) 'MidHandleImage(spaceship.entity) SetScale 1,1 ' Main Loop Repeat Cls ' Clear the screen ' get key inputs to move ship If KeyDown(KEY_LEFT) Then spaceship.applyImpulse(-0.1) If KeyDown(KEY_RIGHT) Then spaceship.applyImpulse(0.1) If KeyDown(KEY_UP) Then spaceship.applyImpulse(0,0.04) ' update and display the ship spaceship.update() spaceship.show() Flip ' display the backbuffer (flip to front buffer) Until KeyHit(KEY_ESCAPE)
Spaceship OOP
VERSION 2 of 2
Rem 1/3/2005 Bill Radford Spaceship Movement tutorial-- Version 2 "A Little More OOP" In this episode I am incorporating some ideas and insights from fellow BlitzMAXers to make the code a little more OOPy. Significantly, We added a function called create that will act as sort of a "Spaceship Object Factory". We also are using a LINKED LIST to hold our objects. Thanks to PERTURBIO for the key-binding and check controls methods as well as other OOP enhancements End Rem Strict ' 'strict' = must declare variables ' VARIABLES Global GW = 800 ' Graphics Height Global GH = 600 ' Graphics Width Global GD = 0 ' Graphics Depth "0" means Windowed Mode Global MID_GH = GH/2 ' Middle of the screen Height (Y) Global MID_GW = GW/2 ' Middle of the screen width (X) Global MX,MY ' Used for Mousex() and Mousey() Global ship_list:Tlist = CreateList() ' create a list to hold our ship objects Local ship:player Graphics(GW,GH,GD) ' set graphics mode Rem create an actor type that possess attributes that can be used by may different game characters. Player, enemy, Wizard, etc... The Type "ACTOR" is the beginning of our Object Oriented Programming (OOP) Actor is a Class or Type. It simply is a definition of what an "actor" is. the Fields can also called Attributes. for example, an actor has the x#,y# Fields that will hold the screen x,y coordinates that tell BMAX where to draw it. the actor class also has "Methods". Methods are functions that are unique to that class. the "update" method, for instance, will only work for the actor class. End Rem Type actor ' Field x# = GW/2 ' SCREEN X and Y POSITION (initially the middle) Field y# = GH/2 Field xint:Int ' x,y integers fot neater screen printing Field yint:Int Field name:String ' string contains the text name of actor Field life = 100 ' life force (defaults to 100) Field entity ' a placeholder for the image of the actor ' Field angle# ' angle# = 0 to 360 degrees Field velocity# ' speed of the actor (forward momentum?) Field angular_velocity# ' rotational speed, i.e. how fast it spins Field friction# = 0.99 ' Friction slows down the actor slightly each frame Field rotfriction# = 0.97 ' slows down the rate of spin slightly each frame Method applyImpulse#(angular#,thrust#=0.0) ' add the rotational and/or thrust to the velocities ' these are taken from key inputs. see below angular_velocity# = angular_velocity# + angular# velocity# = velocity# + thrust# End Method Method update() Rem This method calculates the velocity of the ship as well as the angle. It uses the SINE and COSINE of the current ANGLE to determine the direction the ship should travel. The ANGLE is between 0 and 360. both velocities (rotation and forward) are multiplied by a friction amount that will slow the ship down each frame End Rem angular_velocity# = angular_velocity# * rotfriction# velocity# = velocity# * friction ' move the ship forward x=x+(velocity*Cos(angle-90)) y=y+(velocity*Sin(angle-90)) ' Turn the ship angle#:+angular_velocity If angle#<0.0 Then angle#=360.0 If angle#>360.0 Then angle#= 0.00 ' If the actor goes off screen, WRAP to other side If x>GW Then x = 0 If x<0 Then x = GW If y<0 Then y = GH If y>GH Then y=0 End Method Method show() ' This Method is used to draw the current frame of the ship ' as well as the print the x,y and velocity values to the screen xint = x yint = y SetRotation(angle) ' turn spaceship to current angle DrawImage(entity,x,y) SetTransform(0,1.1,1.1) SetColor 0,0,255 DrawRect x-44,y+30,96,15 SetScale 1,1 SetColor 255,255,0 DrawText "x="+xint+" y="+yint,x-40,y+32 DrawText "Velocity = "+velocity,x-40,y+48 End Method End Type Rem Now we create an extended Type called Player. Type Player will INHERIT all of the attributes and methods of actor, as well as add a new field of its own, inventory. the [] at the end indicate an array. inventory is an array of strings. End Rem Type player Extends actor Field inventory:String[] Field _KEYLEFT = KEY_LEFT Field _KEYRIGHT = KEY_RIGHT Field _KEYUP = KEY_UP Field _KEYDOWN = KEY_DOWN Method SetKey(KeyName:String, KeyVal:Byte) Select Lower(KeyName) Case "left" _KEYLEFT = KeyVal Case "right" _KEYRIGHT = KeyVal Case "up" _KEYUP = KeyVal Case "down" _KEYDOWN = KeyVal End Select End Method Method GetKey(KeyName:String) Select Lower(KeyName) Case "left" Return _KEYLEFT Case "right" Return _KEYRIGHT Case "up" Return _KEYUP Case "down" Return _KEYDOWN End Select End Method Method CheckControls() If KeyDown(_KEYLEFT) Then applyImpulse(-0.1) If KeyDown(_KEYRIGHT) Then applyImpulse(0.1) If KeyDown(_KEYUP) Then applyImpulse(0,0.04) End Method ' This is a unique type of function. when called, this function will create a new instance ' of PLAYER. Since functions can be called when there are no existing instances, they can ' be used for this. This adds a nice, tidy way to add new instances of our types, along with ' several attributes (in this case the x,y starting position, name and RGB color) Function create:player(pname$,pox,poy,red,green,blue) Local t:player = New player t.entity = CreateImage(64,64,DYNAMICIMAGE) t.name = pname t.x = pox t.y = poy SetColor red,green,blue SetLineWidth 3 DrawLine 0,64,32,0 DrawLine 32,0,64,64 DrawOval 24,16,16,16 SetColor 255,255,0 DrawText pname,32-(Len(pname)*8)/2,20 GrabImage t.entity,0,0 Cls ; Flip SetImageHandle(t.entity,32,48) SetScale 1,1 ' NEW - we add this INSTANCE of player to the LINKED LIST called ship_list ' so we can iterate through them easily later on ListAddLast ship_list,t Return t End Function End Type Type enemy Extends actor Field anger End Type Rem call the player TYPE's function "create" to create a few instances of type "player" the we will add them to a LIST End Rem ' Create INSTANCES of the type player Global spaceship:player = player.create("Bobby",GW-100,GH/2,0,200,0) Global player2:player = player.create("Kate",100,GH/2,200,0,0) player2.SetKey("left", KEY_A) player2.SetKey("right", KEY_D) player2.SetKey("up", KEY_W) ' Main Loop Repeat Cls ' Clear the screen ' we now have the player types (the ships) in the Linked List (ship_list) ' we can iterate through them and get control inputs, update their position and ' display them to the screen within a FOR EACHIN loop For ship:player = EachIn ship_list ' get key inputs to move ship ship.CheckControls() ship.update() ship.show() next Flip ' display the backbuffer (flip to front buffer) Until KeyHit(KEY_ESCAPE)