step movement of the aliens in space invaders

john2367

New Member
Joined
Feb 19, 2019
Likes
2
#1
Hello I am trying to create the step movement of the aliens in space invaders. However, I am having an issue with some of the aliens separating from the their row when they touch the left edge of the screen as shown below


This doesn't happen when an alien touches the right side of the screen

If it is of any help, the aliens also move downwards when they touch any of the horizontal edges.


Cerberus X:
Import mojo

Function Main:Int()
    New CGame()
End Function

Global n:= 0.1
Global screenX:Int = 640

Class CGame Extends App
    Field x:Float
    Field lastTick:Int
    Field counter:Float= n    ' Sixty seconds
    Field alienSpr:Image[]
   
    Field alienList:List<Enemy>
    Field alienList2:List<Enemy>
    Field alienList3:List<Enemy>
    Field alienList4:List<Enemy>
    Field alienList5:List<Enemy>

    Method OnCreate()
        SetUpdateRate(60)
        alienList = New List <Enemy>
        alienList2 = New List <Enemy>
        alienList3= New List <Enemy>
        alienList4 = New List <Enemy>
        alienList5 = New List <Enemy>
       
        alienSpr =alienSpr.Resize(8)
       
        alienSpr[0] = LoadImage("alien1.png")
        alienSpr[1] = LoadImage("alien1.png")
        alienSpr[2] = LoadImage("alien2.png")
        alienSpr[3]= LoadImage("crab1.png")
        alienSpr[4] = LoadImage("crab2.png")
        alienSpr[5] = LoadImage("squid1.png")
        alienSpr[6] = LoadImage("squid2.png")
       
        alienSpr[7] = LoadImage("ufo.png")
       
        For Local i:Int = 0 To 10      
            alienList.AddLast(New Enemy(170+(i*28),60))
            alienList2.AddLast(New Enemy(170+(i*28),88))
            alienList3.AddLast(New Enemy(170+(i*28),116))
            alienList4.AddLast(New Enemy(170+(i*28),144))
            alienList5.AddLast(New Enemy(170+(i*28),172))
        Next
    End Method
   
    Method OnUpdate()
        Local tick:= Millisecs()
       
'this section is just for the timer
        If tick >= Self.lastTick+(1000*n) And counter>-1
            Self.counter -= n
            Self.lastTick = tick          
        Endif
       
        If Self.counter < 0 Then
            'Local Seed
            'x = Rnd(0.1,1.0)
            Self.counter = n
            Move(alienList)
            Move(alienList2)
            Move(alienList3)
            Move(alienList4)
            Move(alienList5)
        Endif
       

    End Method
   
    Method OnRender()
        Cls
        RenderAlien()

    End Method
   
    Method RenderAlien()
    'this section is where the aliens switch their sprites
        For Local alien:=Eachin alienList
            If Self.counter > 0 Then
                DrawImage(alienSpr[5],alien.x+2,alien.y)
            Else
                DrawImage(alienSpr[6],alien.x+2,alien.y)
            Endif
        Next
       
        For Local alien:=Eachin alienList2
            If Self.counter > 0 Then
                DrawImage(alienSpr[1],alien.x,alien.y)
            Else
                DrawImage(alienSpr[2],alien.x,alien.y)
            Endif
        Next
       
        For Local alien:=Eachin alienList3
            If Self.counter > 0 Then
                DrawImage(alienSpr[1],alien.x,alien.y)
            Else
                DrawImage(alienSpr[2],alien.x,alien.y)
            Endif
        Next
       
        For Local alien:=Eachin alienList4
            If Self.counter > 0 Then
                DrawImage(alienSpr[3],alien.x,alien.y)
            Else
                DrawImage(alienSpr[4],alien.x,alien.y)
            Endif
        Next
       
        For Local alien:=Eachin alienList5
            If Self.counter > 0 Then
                DrawImage(alienSpr[3],alien.x,alien.y)
            Else
                DrawImage(alienSpr[4],alien.x,alien.y)
            Endif
        Next
    End
End Class

Class Enemy
    Field x:Int = 10
    Field y:Int = 50
    Field speed:Int = 10
   
    Method Move:Int(speed:Int)
        x+=speed
'just some validations for the movement
        If x>screenX-20 Then x = 620
        If x<10 Then x = 9
    End
   
    Method New(xPos:Int,yPos:Int)
        x=xPos
        y=yPos
    End
End

'this is where the problem is located i think
Function Move(list:List<Enemy>)

    For Local alien:=Eachin list    'movement of aliens
        alien.Move(alien.speed)
       
        If alien.x > screenX-40 Then    'when an alien touches the right edge of the screen
            For Local alien2:=Eachin list
                alien2.y+=20
                alien2.speed *=-1
            Next
           
        Elseif alien.x<10 Then    'when an alien touches the left edge of the screen
            For Local alien2:=Eachin list
                alien2.y+=20
                alien2.speed *=-1
               
            Next
        Endif
    Next
   
End
 
Last edited:

dawlane

Active Member
CX Code Contributor
Joined
Jun 21, 2017
Likes
198
#3
I think I can see what's happening.
When you are iterating the alien movement, you have changed the x position and then tried to update the speed based on the new x being on the screen edge. Iterating again while in the main iteration is the problem, as there is the possibility that x could still be out side of the screen bounds, eventually a column will go out of sync.

To make it work you will have to iterate twice, first you update all x positions and the iterate again to check if any alien is pass the screen edge to move down a row.

Cerberus X:
Function Move(list:List<Enemy>)

    ' Move horizontal
    For Local alien:=Eachin list
        alien.Move(alien.speed)
    Next
   
    ' Screen edge move down a row.
    For Local alien:=Eachin list
        If alien.x>screenX-40 Or alien.x<10
            For Local alien:=Eachin list
                alien.y+=20
                alien.speed *=-1
            Next
        Endif
    Next
   
End
 

john2367

New Member
Joined
Feb 19, 2019
Likes
2
#4
I kind of solved the problem by adding another variable called row.
Cerberus X:
Function Move(list:List<Enemy>)
    Local row:Int = 0    'row variable
    For Local alien:=Eachin list    'movement of aliens
        alien.Move(alien.speed)
     
        If alien.x > screenX-40 Then    'when an alien touches the right edge of the screen
            For Local alien2:=Eachin list
                alien2.y+=20
                alien2.speed *=-1
            Next
            row+=1    'add 1 to row
         
        Elseif alien.x<10 Then    'when an alien touches the left edge of the screen
            For Local alien2:=Eachin list
                alien2.y+=20
                alien2.speed *=-1
             
            Next
            alien.x+=20+row*20    'reupdate the x position by adding multiples of 20
        Endif
    Next
 
End
I then used the row variable to reupdate the x positions. 20 because the speed is 10 and it doubles for some reason. And as the aliens go down a row the gap doubles as well.


Thanks for all the help
 
Last edited:

magic

Member
3rd Party Tool Dev
Joined
Mar 5, 2018
Likes
18
#6
I loveeeee Space invadersssssss!!
When I first see the graphic... it make me feel happy^^
(This make me realize that I'm old... huhu)
 
Last edited:

MikeHart

Administrator
Staff member
Joined
Jun 19, 2017
Likes
427
Location
Germany
#8
They are so close to the originals, I think it would be better to take them offline. No need for a CnD letter from Hasbro aka Atari. :)
 
Top Bottom