You could write 2D games on the CanvasGadget

Everything else that doesn't fall into one of the other PB categories.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: You could write 2D games on the CanvasGadget

Post by netmaestro »

iirc I never said you should use a canvas for 2D games, only that its graphics performance is good enough that you could. If you did you'd also have to write your own collision routines. Anyway, that said, here's a small demo moving thousands of objects on a canvas gadget. You be the judge if it would support a 2D game or not. Turn the debugger off for smoothest results:

Code: Select all

Structure shrapnel
  x.f 
  y.f 
  u.f 
  v.f 
  life.f 
  s.f
  c.l
EndStructure 

Global NewList dot.shrapnel() 

CreateImage(0, 64, 64, 32|#PB_Image_Transparent)
StartDrawing(ImageOutput(0))
  DrawingMode(#PB_2DDrawing_Gradient|#PB_2DDrawing_AllChannels)      
  BackColor (RGBA(0,0,255,255))
  FrontColor(RGBA(0,0,0,0))
  EllipticalGradient(20, 20, 64, 64)
  Circle(31, 31, 31)   
StopDrawing() 

CreateImage(1, 64, 64, 32|#PB_Image_Transparent)
StartDrawing(ImageOutput(1))
  DrawingMode(#PB_2DDrawing_Gradient|#PB_2DDrawing_AllChannels)      
  BackColor (RGBA(255,0,0,255))
  FrontColor(RGBA(0,0,0,0))
  EllipticalGradient(20, 20, 64, 64)
  Circle(31, 31, 31)   
StopDrawing() 

OpenWindow(0,0,0,640,480,"",#PB_Window_ScreenCentered|#PB_Window_SystemMenu) 
CanvasGadget(0,0,0,640,480)

Procedure BlowemUp(spotx,spoty) 
  For g=0 To 900 
    AddElement(dot()) 
    angle.f=Random(359)*3.141592/180 
    dot()\life=1+Random(254) 
    dot()\u=Cos(angle)*Random(128)/64 
    dot()\v=Sin(angle)*Random(128)/64 
    dot()\v=dot()\v-2  
    dot()\x=spotx 
    dot()\y=spoty 
    dot()\s=Random(15)/10 
    dot()\c = Random($FFFFFF)
  Next g 
EndProcedure 

x=0:y=0:quit=0:f=1:d=1:rt=576:bt=416:x1=350:y1=100:f1=1:d1=1
Repeat 
  ev=WindowEvent()
  While ev
    If ev=#PB_Event_CloseWindow:quit=1:EndIf
    ev=WindowEvent()
  Wend
  
  If f:x+1:If x>=rt:f=0:EndIf:Else:x-1:If x<=0:f=1:EndIf:EndIf
  If d:y+1:If y>=bt:d=0:EndIf:Else:y-1:If y<=0:d=1:EndIf:EndIf  
  If f1:x1+1:If x1>=rt:f1=0:EndIf:Else:x1-1:If x1<=0:f1=1:EndIf:EndIf
  If d1:y1+1:If y1>=bt:d1=0:EndIf:Else:y1-1:If y1<=0:d1=1:EndIf:EndIf  
  
  StartDrawing(CanvasOutput(0)) 
    Box(0,0,640,480,$000000)
    DrawAlphaImage(ImageID(0),x,y)
    DrawAlphaImage(ImageID(1),x1,y1)
    If ListSize(dot())<400 
      BlowemUp(100+Random(480),100+Random(280)) 
    EndIf 
    ForEach dot() 
      dot()\x=dot()\x+dot()\u 
      dot()\y=dot()\y+dot()\v 
      dot()\v=dot()\v+0.05 
      If dot()\x=>(0) And dot()\x<=(639) And dot()\y=>(0) And dot()\y<=(479)
        c=dot()\life 
        c=c+c<<8+c<<16 
        Circle(dot()\x,dot()\y,1,dot()\c) 
      EndIf 
      dot()\life=dot()\life-1:If dot()\life<=0:DeleteElement(dot()):EndIf 
    Next 
  StopDrawing() 
  
  Delay(5)
Until quit
End 
Last edited by netmaestro on Mon Jul 18, 2011 8:37 pm, edited 1 time in total.
BERESHEIT
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4954
Joined: Sun Apr 12, 2009 6:27 am

Re: You could write 2D games on the CanvasGadget

Post by RASHAD »

This is out of the discussion
Fantastic NM; just beautiful
Keep going

Edit :The moving of the balls not smooth
Egypt my love
User avatar
luis
Addict
Addict
Posts: 3895
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: You could write 2D games on the CanvasGadget

Post by luis »

CanvasGadget is very useful and a very nice addition, but I would expect that kind of performance graphic-wise even without it.
What I mean is I think the normal GDI api performance is in the same league, and that something like the demo posted above by netmaestro can be achieved using normal GDI api on bitmap for example, or an imagegadget. Am I wrong ? I didn't try to do same thing, but I remember some times ago I did a star wars like scroller (the text scrolling up with perspective correction) using GDI and was smooth.
After all current graphic card drivers accelerate most if not all of the desktop drawing, and from Vista and beyond the desktop is in reality a graphic screen like the one in a game.

So... I'm not so surprised, but as I said I do not tried to do a direct comparison.
"Have you tried turning it off and on again ?"
User avatar
Andre
PureBasic Team
PureBasic Team
Posts: 2139
Joined: Fri Apr 25, 2003 6:14 pm
Location: Germany (Saxony, Deutscheinsiedel)
Contact:

Re: You could write 2D games on the CanvasGadget

Post by Andre »

@netmaestro: nice example! :D

To make it compile/run on MacOS (and probably Linux too) just replace the Win-only constants #White by $FFFFFF and #Black by $000000 :wink:
Bye,
...André
(PureBasicTeam::Docs & Support - PureArea.net | Order:: PureBasic | PureVisionXP)
rsts
Addict
Addict
Posts: 2736
Joined: Wed Aug 24, 2005 8:39 am
Location: Southwest OH - USA

Re: You could write 2D games on the CanvasGadget

Post by rsts »

Another fabulous canvasGadget example.

Between your and einander's http://www.purebasic.fr/english/viewtop ... 12&t=46933 examples it would certainly seem possible.

This stuff is great. Thanks for sharing.
User avatar
Demivec
Addict
Addict
Posts: 4270
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: You could write 2D games on the CanvasGadget

Post by Demivec »

The example works just as well using an ImageGadget() instead of a CanvasGadget().

Here's the changes that need to be made:

Code: Select all

;add this before the OpenWindow()
CreateImage(2, 640, 480)

;change
;CanvasGadget(0,0,0,640,480) to 
ImageGadget(0,0,0,640,480, ImageID(2))

;change
;StartDrawing(CanvasOutput(0)) to
StartDrawing(ImageOutput(2)) 

;add after the StopDrawing() in the event loop
SetGadgetState(0,ImageID(2))
I didn't see a difference between using an ImageGadget() and using a CanvasGadget().


A CanvasGadget() only has advantages in what it can do that an ImageGadget() can't, namely its ability to react to more events.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: You could write 2D games on the CanvasGadget

Post by netmaestro »

In the CanvasGadget double-buffering is automatic; You can simply write to CanvasOutPut() and there is no need to draw to an image first and then switch outputs (manual double-buffering). Also, the image contained in an ImageGadget must be 24bits depth or you will experience remarkable flickering on rapid updates. If you want to layer your window and have true-to-desktop transparency with alphablending, the CanvasGadget will be superior to the ImageGadget in this regard because CanvasOutput doesn't suffer from the alpha-redraw flicker problem. Yes it can be done by alphablending to a 24bit image and swapping the contained image in an ImageGadget, I'm aware of that. I covered this five years ago here: http://www.purebasic.fr/english/viewtop ... 12&t=18587 My point is that the CanvasGadget automates this for you and CanvasOutput is simpler to implement.
BERESHEIT
eesau
Enthusiast
Enthusiast
Posts: 589
Joined: Fri Apr 27, 2007 12:38 pm
Location: Finland

Re: You could write 2D games on the CanvasGadget

Post by eesau »

Nice example maestro! However, I get the tiniest, slightest of tearing (flicker). Can be seen easily when looking at the red ball, especially if the explosions are disabled.
MachineCode
Addict
Addict
Posts: 1482
Joined: Tue Feb 22, 2011 1:16 pm

Re: You could write 2D games on the CanvasGadget

Post by MachineCode »

eesau wrote:I get the tiniest, slightest of tearing (flicker).
Must be a video driver issue. I have a low-end PC (dual-core CPU) and low-end video card (nVidia 8400 GS) and I get no flickering or tearing at all, and the smoothness and speed is exactly the same no matter if I run the example with the debugger on or off.
Microsoft Visual Basic only lasted 7 short years: 1991 to 1998.
PureBasic: Born in 1998 and still going strong to this very day!
eesau
Enthusiast
Enthusiast
Posts: 589
Joined: Fri Apr 27, 2007 12:38 pm
Location: Finland

Re: You could write 2D games on the CanvasGadget

Post by eesau »

MachineCode wrote:
eesau wrote:I get the tiniest, slightest of tearing (flicker).
Must be a video driver issue. I have a low-end PC (dual-core CPU) and low-end video card (nVidia 8400 GS) and I get no flickering or tearing at all, and the smoothness and speed is exactly the same no matter if I run the example with the debugger on or off.
Mine is a low-end dual-core as well, with nVidia 9800 GT with latest drivers and Windows 7. Tested with both debugger on and off. Granted, the tearing was pretty minuscule. Maybe I'll test again.
MachineCode
Addict
Addict
Posts: 1482
Joined: Tue Feb 22, 2011 1:16 pm

Re: You could write 2D games on the CanvasGadget

Post by MachineCode »

I have XP, if that makes any difference. It might, as 7 has extra slowness.
Microsoft Visual Basic only lasted 7 short years: 1991 to 1998.
PureBasic: Born in 1998 and still going strong to this very day!
User avatar
einander
Enthusiast
Enthusiast
Posts: 744
Joined: Thu Jun 26, 2003 2:09 am
Location: Spain (Galicia)

Re: You could write 2D games on the CanvasGadget

Post by einander »

Very nice example Netmaestro! :D
User avatar
luis
Addict
Addict
Posts: 3895
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: You could write 2D games on the CanvasGadget

Post by luis »

Demivec wrote:The example works just as well using an ImageGadget() instead of a CanvasGadget().
Thank you, yesterday I was too lazy to try it by myself :)
"Have you tried turning it off and on again ?"
Polo
Addict
Addict
Posts: 2422
Joined: Tue May 06, 2003 5:07 pm
Location: UK

Re: You could write 2D games on the CanvasGadget

Post by Polo »

MachineCode wrote:I have XP, if that makes any difference. It might, as 7 has extra slowness.
7 is a LOT slower indeed, didn't they drop the hardware accelerated support on GDI on 7?
User avatar
Demivec
Addict
Addict
Posts: 4270
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: You could write 2D games on the CanvasGadget

Post by Demivec »

netmaestro wrote:In the CanvasGadget double-buffering is automatic; You can simply write to CanvasOutPut() and there is no need to draw to an image first and then switch outputs (manual double-buffering). Also, the image contained in an ImageGadget must be 24bits depth or you will experience remarkable flickering on rapid updates. If you want to layer your window and have true-to-desktop transparency with alphablending, the CanvasGadget will be superior to the ImageGadget in this regard because CanvasOutput doesn't suffer from the alpha-redraw flicker problem. Yes it can be done by alphablending to a 24bit image and swapping the contained image in an ImageGadget, I'm aware of that. I covered this five years ago here: http://www.purebasic.fr/english/viewtop ... 12&t=18587 My point is that the CanvasGadget automates this for you and CanvasOutput is simpler to implement.
True, the double buffering is automatic, but you are simply saving a single SetGadgetState().

I can't comment on the true-to-desktop transparency with alphablending in a layered window. That seems to be a very isolated issue and one I don't have a good example of to compare between using a CanvasGadget and an ImageGadget. The current results seem to be identical with a 24bit image. How can you tell if the default image used for the CanvasGadget is 24bit or 32bit? I know the ImageID of the image can be retrieved but that is as far as I can get without API.
Post Reply