Page 1 of 1

Camera

Posted: Thu Jul 28, 2011 1:56 pm
by Nubcake
Edited:

I want to create a test 2D game where when my character moves out of the screen the camera moves slowly to his position which is also known as scrolling. I have created a map (village.png) with a level editor of size 800*720 and it is destined to have the camera size as 160*144 pixels. But how do i maintain the camera size while on a window of 640*480?
Is there some sort of library for this (2D scrolling) or do i have to make my sprites very big?

Re: Camera

Posted: Thu Jul 28, 2011 2:39 pm
by citystate
you are mixing 2d and 3d libraries
either use Camera and RenderWorld (making sure you build some 3d object for the camera to look at)
or use Sprite and FlipBuffers (moving the Screen background instead of the camera)

Re: Camera

Posted: Thu Jul 28, 2011 9:52 pm
by Comtois
may be this can help ? In this example i have 2 cameras :
Camera one use keys : Up , down, left and Right
Camera two use keys : Z, S, Q And D (on my azerty keyboard)
Both camera use the same map.

Code: Select all

; Comtois 
; PB 4.51
 
InitSprite()
InitKeyboard()
OpenScreen(1024,768,32,"Map")
 
KeyboardMode(#PB_Keyboard_International)
Enumeration
  #Herbe
  #Eau
  #Fleur
  #Arbre
  #Bord
EndEnumeration
 
Structure s_Point
  x.i
  y.i
EndStructure
 
Structure s_Screen
  Width.i
  Height.i
EndStructure
Structure S_Box
  x.i
  y.i
  Width.i
  Height.i
EndStructure
 
Structure s_Commande
  Haut.i
  Bas.i
  Gauche.i
  Droite.i
EndStructure
 
Structure s_Camera
  Position.s_Point
  Destination.s_Point
  Speed.i
  Screen.s_Screen ; Dimension de l'écran
  ViewPort.s_Box
  Touche.s_Commande
EndStructure
 
#TailleTitleCarteX=440
#TailleTitleCarteY=440
#TailleTitle=32
 
Declare DessineSprite(Sprite, Couleur)
Declare RandomMap()
Declare CameraEvent(*Camera.s_Camera)
Declare AfficheMap(*Camera.s_Camera)
Declare AfficheBox(*Camera.s_Camera)
 
 
Camera.s_Camera
Camera\Speed = 3
Camera\Position\x = 0
Camera\Position\y = 0
Camera\ViewPort\x = 40
Camera\ViewPort\y = 40
Camera\ViewPort\Width = 300
Camera\ViewPort\Height = 150
Camera\Touche\Bas    = #PB_Key_Down
Camera\Touche\Haut   = #PB_Key_Up
Camera\Touche\Droite = #PB_Key_Right
Camera\Touche\Gauche = #PB_Key_Left
 
Camera2.s_Camera
Camera2\Speed = 3
Camera2\Position\x = 0
Camera2\Position\y = 0
Camera2\ViewPort\x = 40
Camera2\ViewPort\y = 240
Camera2\ViewPort\Width = 300
Camera2\ViewPort\Height = 150
Camera2\Touche\Bas    = #PB_Key_S
Camera2\Touche\Haut   = #PB_Key_Z
Camera2\Touche\Droite = #PB_Key_D
Camera2\Touche\Gauche = #PB_Key_Q
 
DessineSprite(#Bord, $0000FF)
DessineSprite(#Herbe, $00FF00)
DessineSprite(#Eau, $FF0000)
DessineSprite(#Fleur, $00FFFF)
DessineSprite(#Arbre, $000088)
 
Global Dim Map(#TailleTitleCarteX,#TailleTitleCarteY)
RandomMap()
 
Repeat
  ClearScreen(0)
  CameraEvent(@Camera)
  AfficheMap(@Camera)
  AfficheBox(@Camera)
  CameraEvent(@Camera2)
  AfficheMap(@Camera2)
  AfficheBox(@Camera2)
  FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)
 
Procedure DessineSprite(Sprite, Couleur)
  CreateSprite(Sprite,#TailleTitle,#TailleTitle)
  If StartDrawing(SpriteOutput(Sprite))
    Box(0,0,SpriteWidth(Sprite),SpriteHeight(Sprite),Couleur)
    StopDrawing()
    ProcedureReturn #True
  EndIf
EndProcedure
 
Procedure RandomMap()
  For y=0 To #TailleTitleCarteY
    For x=0 To #TailleTitleCarteX
      If x=0 Or x=#TailleTitleCarteX Or y=0 Or y=#TailleTitleCarteY Or x=#TailleTitleCarteX/2 Or y=#TailleTitleCarteY/2
        Map(x,y)=#Bord
      Else
        Map(x,y)=Random(#Arbre)
      EndIf   
    Next x
  Next y   
EndProcedure
 
Procedure AfficheBox(*Camera.s_Camera)
  StartDrawing(ScreenOutput())
    DrawingMode(#PB_2DDrawing_Outlined)
    Box(*Camera\ViewPort\x, *Camera\ViewPort\y, *Camera\ViewPort\Width, *Camera\ViewPort\Height,$FFFFFF)
  StopDrawing()
EndProcedure
 
Procedure CameraEvent(*Camera.s_Camera)
 
  If ExamineKeyboard()
 
    If KeyboardPushed(*Camera\Touche\Droite)
      Key_Right = #True
    EndIf
    If KeyboardReleased(*Camera\Touche\Droite)
      Key_Right = #False
    EndIf     
    If KeyboardPushed(*Camera\Touche\Gauche)
      Key_Left = #True
    EndIf
    If KeyboardReleased(*Camera\Touche\Gauche)
      Key_Left = #False
    EndIf     
    If KeyboardPushed(*Camera\Touche\Haut)
      Key_Up = #True
    EndIf
    If KeyboardReleased(*Camera\Touche\Haut)
      Key_Up = #False
    EndIf 
    If KeyboardPushed(*Camera\Touche\Bas)
      Key_Down = #True
    EndIf
    If KeyboardReleased(*Camera\Touche\Bas)
      Key_down = #False
    EndIf         
  EndIf
    If Key_Right And *Camera\Position\x < (#TailleTitleCarteX + 1) * #TailleTitle - *Camera\ViewPort\Width
      *Camera\Position\x + *Camera\Speed
    ElseIf Key_Left And *Camera\Position\x > 0
      *Camera\Position\x - *Camera\Speed
    EndIf
    If Key_Down And *Camera\Position\y < (#TailleTitleCarteY + 1) * #TailleTitle - *Camera\ViewPort\Height
      *Camera\Position\y + *Camera\Speed
    ElseIf Key_Up And *Camera\Position\y > 0
      *Camera\Position\y - *Camera\Speed
    EndIf 
 
EndProcedure 
 
Procedure AfficheMap(*Camera.s_Camera)
  Define.i Tx, Ty  ; Index sur le tableau DataMap pour récupérer le numéro du Tile à afficher
  Define.i Rx, Ry  ; Position sur le Tile à afficher (entre 0 et la largeur ou hauteur du Tile à afficher)
  Define.i Px, Py  ; Position à l'écran du Tile à afficher
  Define.S_Box Src ; Portion de l'image à récupérer sur le Chipset (Tile à afficher) 
 
  Tx         = *Camera\Position\x / #TailleTitle 
  Ty         = *Camera\Position\y / #TailleTitle
  Ry         = *Camera\Position\y % #TailleTitle
  Src\y      = Ry
  Src\Height = #TailleTitle - Ry
  Py         = *Camera\ViewPort\y
 
 
  While Py < *Camera\ViewPort\y + *Camera\ViewPort\Height
    Px        = *Camera\ViewPort\x   
    Rx        = *Camera\Position\x % #TailleTitle
    Tx        = *Camera\Position\x / #TailleTitle    
    Src\x     = Rx
    Src\Width = #TailleTitle - Rx
 
    While Px < *Camera\ViewPort\x + *Camera\ViewPort\Width
      ClipSprite(Map(Tx,Ty), Src\x, Src\y, Src\Width, Src\Height)
      DisplaySprite(Map(Tx,Ty), Px, Py)
 
      ;On se place après le Tile qui vient d'être affiché      
      Px + Src\Width
      ;On calcule le prochain Tile à afficher 
      Tx + 1
      ;
      Src\x = 0
      ;Tant que l'on n'atteint pas l'extrémité de la carte, le Tile sera complet 
      Src\Width = #TailleTitle
      ;sinon il faut calculer sa largeur
      If (Px + Src\Width) > (*Camera\ViewPort\x + *Camera\ViewPort\Width)
        Src\Width = *Camera\ViewPort\x + *Camera\ViewPort\Width - Px
      EndIf
 
    Wend
    ;On se place après le Tile qui vient d'être affiché
    Py + Src\Height
    ;On calcule le prochain Tile à afficher (index sur le tableau 
    Ty + 1
    ;
    Src\y      = 0
    ;Tant que l'on n'atteint pas l'extrémité de la carte, le Tile sera complet 
    Src\Height = #TailleTitle
    ;sinon il faut calculer sa hauteur
    If Py + Src\Height > *Camera\ViewPort\y + *Camera\ViewPort\Height
      Src\Height = *Camera\ViewPort\y + *Camera\ViewPort\Height - Py
    EndIf
  Wend  
 
EndProcedure
Or this example ; Download (blendman is the author of the images)

Re: Camera

Posted: Thu Jul 28, 2011 10:15 pm
by Comtois
Nubcake wrote:Edited:
I have created a map (village.png) with a level editor of size 800*720 and it is destined to have the camera size as 160*144 pixels. But how do i maintain the camera size while on a window of 640*480?
Is there some sort of library for this (2D scrolling) or do i have to make my sprites very big?
Use

Code: Select all

LoadSprite(#Village, "Village.png")
ClipSprite(#Village, CameraX, CameraY, 160, 144)
DisplaySprite(#Village, x, y)
and use keyboard to increment or decrement CameraX and CameraY.

Re: Camera

Posted: Thu Jul 28, 2011 10:44 pm
by Nubcake
thanks for the replies , i've adapted a similar way to do it. edit: Found it.