新建X2 GAME
新建的游戏工程
B4A公司在2018年推出了名为X2 GAME的游戏框架, 这个游戏库可用于安卓、苹果、WIN环境的软件开发。B4A v12.8 开发环境里面,可以通过新建菜单命令创建一个X2 GAME游戏框架,这是一个赛车游戏。
X2 GAME游戏库最初是发表在 [B4X] X2 / XUI2D (Box2D) - Game engine
赛车游戏运行截图
Main窗体代码如下:
#Region Project Attributes
#ApplicationLabel: Hello World
#VersionCode: 1
#VersionName:
#SupportedOrientations: sensorLandscape
#CanInstallToExternalStorage: False
#End Region
#Region Activity Attributes
#FullScreen: True
#IncludeTitle: false
#End Region
#BridgeLogger: True
Sub Process_Globals
Public ActionBarHomeClicked As Boolean
End Sub
Sub Globals
End Sub
Sub Activity_Create(FirstTime As Boolean)
SetImmersiveMode
Dim pm As B4XPagesManager
pm.Initialize(Activity)
End Sub
Private Sub SetImmersiveMode
Activity_WindowFocusChanged(True)
Dim lv As LayoutValues = GetRealSize
Dim jo As JavaObject = Activity
jo.RunMethod("setBottom", Array(lv.Height))
jo.RunMethod("setRight", Array(lv.Width))
Activity.Height = lv.Height
Activity.Width = lv.Width
End Sub
Sub GetRealSize As LayoutValues
Dim lv As LayoutValues
Dim ctxt As JavaObject
ctxt.InitializeContext
Dim display As JavaObject = ctxt.RunMethodJO("getSystemService", Array("window")).RunMethod("getDefaultDisplay", Null)
Dim point As JavaObject
point.InitializeNewInstance("android.graphics.Point", Null)
display.RunMethod("getRealSize", Array(point))
lv.Width = point.GetField("x")
lv.Height = point.GetField("y")
lv.Scale = 100dip / 100
Return lv
End Sub
Sub Activity_WindowFocusChanged(HasFocus As Boolean)
If HasFocus Then
Try
Dim jo As JavaObject = Activity
Sleep(300)
jo.RunMethod("setSystemUiVisibility", Array As Object(5894)) '3846 - non-sticky
Catch
'Log(LastException) 'This can cause another error
End Try 'ignore
End If
End Sub
'Template version: B4A-1.01
#Region Delegates
Sub Activity_ActionBarHomeClick
ActionBarHomeClicked = True
B4XPages.Delegate.Activity_ActionBarHomeClick
ActionBarHomeClicked = False
End Sub
Sub Activity_KeyPress (KeyCode As Int) As Boolean
Return B4XPages.Delegate.Activity_KeyPress(KeyCode)
End Sub
Sub Activity_Resume
B4XPages.Delegate.Activity_Resume
End Sub
Sub Activity_Pause (UserClosed As Boolean)
B4XPages.Delegate.Activity_Pause
End Sub
Sub Activity_PermissionResult (Permission As String, Result As Boolean)
B4XPages.Delegate.Activity_PermissionResult(Permission, Result)
End Sub
Sub Create_Menu (Menu As Object)
B4XPages.Delegate.Create_Menu(Menu)
End Sub
#if Java
public boolean _onCreateOptionsMenu(android.view.Menu menu) {
processBA.raiseEvent(null, "create_menu", menu);
return true;
}
#End If
#End Region
'Program code should go into B4XMainPage and other pages.
类B4XMainPage代码如下:
#Region Shared Files
#CustomBuildAction: folders ready, %WINDIR%\System32\Robocopy.exe,"..\..\Shared Files" "..\Files"
'Ctrl + click to sync files: ide://run?file=%WINDIR%\System32\Robocopy.exe&args=..\..\Shared+Files&args=..\Files&FilesSync=True
#End Region
'Ctrl + click to export as zip: ide://run?File=%B4X%\Zipper.jar&Args=Project.zip&VMArgs=-DZeroSharedFiles%3DTrue
Sub Class_Globals
Private Root As B4XView
Private xui As XUI
Public mGame As Game
End Sub
Public Sub Initialize
' B4XPages.GetManager.LogEvents = True
End Sub
'This event will be called once, before the page becomes visible.
Private Sub B4XPage_Created (Root1 As B4XView)
Root = Root1
If Root.Width = 0 Or Root.Height = 0 Then
Wait For B4XPage_Resize(Width As Int, Height As Int)
End If
mGame.Initialize(Root)
mGame.X2.Start
End Sub
Private Sub B4XPage_Resize (Width As Int, Height As Int)
mGame.Resize
End Sub
Private Sub B4XPage_Appear
If mGame.IsInitialized And mGame.X2.IsRunning = False Then
mGame.X2.Start
End If
End Sub
Private Sub B4XPage_Disappear
If mGame.IsInitialized Then
mGame.X2.Stop
End If
End Sub
类Game代码如下:
Sub Class_Globals
Public X2 As X2Utils
Private xui As XUI 'ignore
Public world As B2World
Public Ground As X2BodyWrapper
Private ivForeground As B4XView
Private ivBackground As B4XView
Public lblStats As B4XView
Public TileMap As X2TileMap
Public Const ObjectLayer As String = "Object Layer 1"
Private PanelForTouch As B4XView
Private Car As X2BodyWrapper
Private force As B2Vec2
Private Multitouch As X2MultiTouch
Private sound As X2SoundPool
End Sub
'The example files are located in the Shared Files folder and in each of the projects Files folder. In most cases you will want to delete all these files, except of the layout files.
Public Sub Initialize (Parent As B4XView)
Parent.LoadLayout("GameLayout")
world.Initialize("world", world.CreateVec2(0, 0))
X2.Initialize(Me, ivForeground, world)
Dim WorldWidth As Float = 10 'meters
Dim WorldHeight As Float = WorldWidth / 1.333 'same ratio as in the designer script
X2.ConfigureDimensions(world.CreateVec2(WorldWidth / 2, WorldHeight / 2), WorldWidth)
'comment to disable debug drawing
'X2.EnableDebugDraw
TileMap.Initialize(X2, File.DirAssets, "hello world with background.json", ivBackground)
'We want the tiles to be square. Otherwise we will have issues with rotated tiles.
Dim TileSize As Int = Min(X2.MainBC.mWidth / TileMap.TilesPerRow, X2.MainBC.mHeight / TileMap.TilesPerColumn)
TileMap.SetSingleTileDimensionsInBCPixels(TileSize, TileSize)
'Update the world center based on the map size
SetWorldCenter
TileMap.PrepareObjectsDef(ObjectLayer)
'create the two borders
TileMap.CreateObject2(ObjectLayer, 9)
TileMap.CreateObject2(ObjectLayer, 10)
'create the car
Car = TileMap.CreateObject2ByName(ObjectLayer, "car")
'add the car front and connect it to the car with a WeldJoint.
Dim front As X2BodyWrapper = TileMap.CreateObject2ByName(ObjectLayer, "car front")
Dim weld As B2WeldJointDef
weld.Initialize(Car.Body, front.Body, front.Body.WorldCenter)
X2.mWorld.CreateJoint(weld)
force = X2.CreateVec2(0, 0.5)
Multitouch.Initialize(B4XPages.MainPage, Array(PanelForTouch))
sound.Initialize
sound.AddSound("click", File.DirAssets, "click.mp3")
End Sub
Private Sub SetWorldCenter
'The map size will not be identical to the screen size. This happens because the tile size in (bc) pixels needs to be a whole number.
'So we need to update the world center and move the map to the center.
X2.UpdateWorldCenter(TileMap.MapAABB.Center)
End Sub
Public Sub Resize
X2.ImageViewResized
End Sub
Public Sub Tick (GS As X2GameStep)
TileMap.DrawScreen(Array("Tile Layer 1"), GS.DrawingTasks)
Dim touch As X2Touch = Multitouch.GetSingleTouch(PanelForTouch)
If touch.IsInitialized Then
Car.Body.ApplyForceToCenter(Car.Body.Transform.MultiplyRot(force))
If touch.Handled = False Then
'check for click on car:
For Each bw As X2BodyWrapper In X2.GetBodiesIntersectingWithWorldPoint(X2.ScreenPointToWorld(touch.X, touch.Y))
If bw.Name = "car" Then
Car.Body.ApplyAngularImpulse(5)
touch.Handled = True
sound.PlaySound("click")
End If
Next
End If
End If
End Sub
Public Sub DrawingComplete
TileMap.DrawingComplete
End Sub
'Return True to stop the game loop
Public Sub BeforeTimeStep (GS As X2GameStep) As Boolean
Return False
End Sub
'Make sure that the panels event name is set to Panel.
#If B4J
Private Sub Panel_Touch (Action As Int, X As Float, Y As Float)
Multitouch.B4JDelegateTouchEvent(Sender, Action, X, Y)
End Sub
#Else If B4i
Private Sub Panel_Multitouch (Stage As Int, Data As Object)
Multitouch.B4iDelegateMultitouchEvent(Sender, Stage, Data)
End Sub
#End If