html lag?

Dubbsta

Active Member
Joined
Jul 13, 2017
im playing with a ship shooter and made a list of bullets. on keydown it just un loads almost no space between them...a seperate problem i face. the issue is on html build when i press fire everything freezes till i release button then everything goes back to normal, but on win build everything works fine.? any help is great.
 

Phil7

Active Member
3rd Party Tool Dev
Joined
Jun 26, 2017
Could you post some code, so we can reproduce the issue?
 

Dubbsta

Active Member
Joined
Jul 13, 2017
i forgot how to do a code box
Code:
Strict



Import mojo



class Bullets

Field fx:Int , fy:Int

Field canshoot:Bool = true

Field shotFired:Int

Field numBul:Int

Field bspeed:Int = 3



Method New(x:Int,y:Int)





fx = x

fy = y



End



Method Update:Int()



fy -= bspeed



Return 0

End



Method Draw:Int(fire:Image)



DrawImage(fire,fx,fy)

Return 0

End



End



Class ship Extends App



Const WIDTH:Int = 640

Const HEIGHT:Int = 480



Field score:Int = 0



Field _1up:Image

Field lives:Image[3]

Field life:Int = 3

Field lx:Int

Field ly:Int



Field bg:Image

Field p1:Image ,px:Int ,py:int



Field bulletList:List<Bullets> = New List<Bullets>()





Field enemy:Image , ex:Int , ey:Int



Field fire:Image



Field boss:Image , bx:Int , by:Int

Field b_offset:Int

Field bmin:Int

Field bmax:Int

Field bframe:Int = 0

Field hit:Bool = false

Field mid:Int

Field Benergy:Int = 98

Field BenX:Int = 10





Field P_offset:Int

Field min:Int

Field max:Int

Field speed:Int = 5



Method OnCreate:Int()

SetUpdateRate(60)



bg = LoadImage("bg.png",320,480,1,Image.MidHandle)



mid = WIDTH/2



_1up = LoadImage("lives.png",18,14,1,Image.MidHandle)

For Local i:= 0 until life

lives[i] = _1up

End

lx = 400

ly = HEIGHT - _1up.Height()



fire = LoadImage("fire.png",11,19,1,Image.MidHandle)



p1 = LoadImage("player.png",37,34,1,Image.MidHandle)

P_offset = (bg.Width() - p1.Width())/2

px = mid

py = HEIGHT - p1.Height()

min = px - P_offset

max = px + P_offset

boss = LoadImage("boss1.png",183,162,2,Image.MidHandle)

b_offset = (bg.Width() - boss.Width())/2

bx = mid

by = boss.Height() - boss.Height()/2

bmin = bx - b_offset

bmax = bx + b_offset



Return 0

End


 
Method OnUpdate:Int()


If KeyDown(KEY_RIGHT)

px +=speed

Else If KeyDown(KEY_LEFT)

px -=speed

End



If px >= max Then px = max

If px <= min Then px = min



If KeyHit(KEY_A)

life -= 1



End



For Local i:= eachin bulletList

i.Update()

If i.fx > bx - 50 and i.fx < bx +50 and i.fy > by + 40 and i.fy < by + 80 Or i.fx > bx - 91 and i.fx < bx +91 and i.fy > by - 81 and i.fy < by + 41

bulletList.RemoveFirst()

score += 10

hit = True

Benergy -= 1



End



Next

If hit

bframe +=1

If bframe > 1 Then bframe = 0

hit = False

End





If Benergy <= 0



End


If KeyDown(KEY_SPACE)

bulletList.AddLast(New Bullets(px,py-p1.Height()/2))

End



Return 0

End

 
Method OnRender:Int()

Cls 80, 80, 80



DrawImage(bg , WIDTH/2 , HEIGHT/2)
 

For Local i:= Eachin bulletList

i.Draw(fire)

next


DrawImage(p1, px , py)



DrawImage(boss,bx,by,bframe)



For Local i:= 0 until life

DrawImage(lives[i], lx+ i* 30,ly)

Next



SetColor 255,0,0

DrawRect(BenX,40,100,10)

SetColor 0,0,0

DrawRect(BenX+1,41,Benergy,8)



SetColor 0,255,0

DrawText("SCORE: "+ score, 10,10)

Return 0

End

End

    

Function Main:Int()



New ship()



Return 0

End
 
Last edited:

MikeHart

Administrator
Staff member
Joined
Jun 19, 2017
Location
Germany
Okeeeyyy.

1) This code is incomplete.

2) By looking at it, you load the same bullet image all over again. Don't do that. Load it once and assign it to every new bullet you create. The best option would be to even precreate bullets and use them only when needed.
 

Dubbsta

Active Member
Joined
Jul 13, 2017
thanks mike i moved the LoadImage to OnCreate() and that seemed to fix it. i dont know if thats what you meant by load it once and assign it, if not i would like to know what you mean. also im not sure what you mean by pre calc the bullets? thanks for the help!

edit: i aslo updated the code above to reflect the changes
 

Phil7

Active Member
3rd Party Tool Dev
Joined
Jun 26, 2017
I think, what mike meant is some kind of object pooling. you are creating and removing a lot of objects (class instances) , which can slow down your frame rate. It is better to estimate the number of bullets you need and create them in OnCreate(), but with a bool field called active (or visible) set to false. In OnRender() you only draw the bullet if active is true.
So during the game you can switch a bullet on and off whenever needed without ever creating or removing any objects.
 

Dubbsta

Active Member
Joined
Jul 13, 2017
hehe no i dont got it... im not sure how to do that.

in OnCreate() i put
Code:
If shot = 1

For Local i:= 0 To 100

bulletList.AddLast(New Bullets(px,py-p1.Height()/2))

next

End

and in OnUpdate() i put

Code:
If KeyHit(KEY_SPACE)

shot = 1

End
i think im close :\
 

Phil7

Active Member
3rd Party Tool Dev
Joined
Jun 26, 2017
Here is a minimalist example of object pooling. If someone has a simpler/ better example ...

Code:
Strict
Import mojo

Class Bullet
    Field x:Float
    Field y:Float
    Field vx:Float
    Field vy:Float
    Field visible:Bool = False
End Class

Class Game Extends App
  
    Field bulletPool:List<Bullet>
    Field bulletPoolSize:Int = 5
  
    Method OnCreate:Int()  
        SetUpdateRate(60)
      
        bulletPool = New List<Bullet>
        For Local i:Int = 0 Until bulletPoolSize
            bulletPool.AddLast(New Bullet())
        Next
          
        Return 0
    End
  
    Method OnUpdate:Int()
  
        'Update all bullets
        For Local b:Bullet = EachIn bulletPool
            b.x = b.x + b.vx
            b.y = b.y + b.vy
          
            'turn bullet off, if it leaves Area
            If b.x > DeviceWidth() -50
                b.visible = False
            EndIf
        Next
      
        'Check for available bullets in pool, Mouse is clicked
        If MouseHit()
            Print "look for available bullet..."
            For Local b:Bullet = EachIn bulletPool
                If b.visible = False
                Print "...found"
                    b.visible = True
                    b.x = 300
                    b.y = 300
                    b.vx = 2
                    b.vy = -1
                    Exit
                EndIf
            Next  
        EndIf
      
        Return 0
    End
  
    Method OnRender:Int()
        Cls()
        DrawText("Click Mouse to shoot", 10, 10)
        DrawText("Number of pool elements: " + bulletPoolSize, 10, 30)
      
        DrawCircle(300, 300, 20)
      
        'Draw all visible bullets
        For Local b:Bullet = EachIn bulletPool
            If b.visible  
                DrawCircle(b.x, b.y, 5)
            EndIf
        Next

        Return 0
    End
  
End


Function Main:Int()
    New Game()
    Return 0
End
 
Top Bottom