Arrangiert für Pacman, erstellt basierend auf den veröffentlichten Spezifikationen Ich will hinzufügen. Lassen Sie uns Pacman nicht nur durch Wischen, sondern auch durch Berührungs- und Beschleunigungssensor steuern und ein originelles Labyrinth hinzufügen. Der Quellcode ist auf GitHub verfügbar. Bitte beziehen Sie sich darauf.
Fügen Sie ein Konfigurationsmenü hinzu, um zwischen Operationen und Labyrinthen zu wechseln. Für das Hinzufügen des Labyrinths habe ich mich auf die folgenden Spezifikationen in der Entwicklung bezogen.
Fügen Sie CgSceneCreditMode ein Menü hinzu. Nach einer Weile nach dem Einlegen des Guthabens wird in Fall 1 der Eingang des Menüs angezeigt. Wenn Sie es berühren, können Sie das Menü aufrufen.
Informationen zur Struktur der CgSceneFrame-Klasse finden Sie in der vorherigen [Einführung] iOS App Development # 5 [Sequence Design].
/// Credit Mode
class CgSceneCreditMode : CgSceneFrame {
enum EnEvent: Int {
case EnterConfig = 3
case Operation = 5
case ExtraMode = 6
case DebugMode = 7
case Language = 8
case ResetSetting = 9
case ExitConfig = 10
case None
}
private let table_enterConfiguration: [(Int,Int,Int,Int,EnEvent)] = [
( 26, 34, 28, 36, .EnterConfig)
]
private let table_setConfiguration: [(Int,Int,Int,Int,EnEvent)] = [
( 26, 34, 28, 36, .ExitConfig),
( 4, 25, 28, 27, .Operation),
( 4, 20, 28, 22, .ExtraMode),
( 4, 15, 28, 17, .DebugMode),
( 4, 10, 28, 12, .Language),
( 4, 5, 28, 7, .ResetSetting)
]
private var table_search: [(column0:Int,row0:Int,column1:Int,row1:Int,event:EnEvent)] = []
private var configMode: Bool = false
/// Event handler
/// - Parameters:
/// - sender: Message sender
/// - id: Message ID
/// - values: Parameters of message
override func handleEvent(sender: CbObject, message: EnMessage, parameter values: [Int]) {
if message == .Touch {
let position = CgPosition.init(x: CGFloat(values[0]), y: CGFloat(values[1]))
let event = search(column: position.column, row: position.row)
if event == .None {
if !configMode {
stopSequence()
}
} else {
goToNextSequence(event.rawValue)
}
}
}
/// Handle sequence
/// To override in a derived class.
/// - Parameter sequence: Sequence number
/// - Returns: If true, continue the sequence, if not, end the sequence.
override func handleSequence(sequence: Int) -> Bool {
switch sequence {
case 0:
configMode = false
table_search = []
clear()
printFrame()
printPlayerScore()
printHighScore()
printCredit()
printRounds()
background.print(0, color: .Orange, column: 6, row: 19, string: "PUSH START BUTTON")
background.print(0, color: .Cyan, column: 8, row: 15, string: "1 PLAYER ONLY")
if context.language == .English {
background.print(0, color: .Pink, column: 1, row: 11, string: "BONUS PAC-MAN FOR 20000 ]^_")
background.print(0, color: .Purple, column:4, row: 4, string: "@ 2020 HIWAY.KIKUTADA")
} else {
background.print(0, color: .Pink, column: 1, row: 11, string: "BONUS PAC-MAN FOR 10000 ]^_")
background.print(0, color: .Purple, column: 7, row: 7, string: "@ #$%&'()* 2020") // NAMACO
}
goToNextSequence(after: 60*16*2)
case 1:
table_search = table_enterConfiguration
background.print(0, color: .White, column: 27, row: 35, string: "$")
goToNextSequence()
case 2:
// wait for event
break;
case 3:
configMode = true
table_search = table_setConfiguration
background.fill(0, texture: 0)
printFrame()
printPlayerScore()
printHighScore()
printCredit()
background.print(0, color: .White, column: 27, row: 35, string: "#")
background.print(0, color: .Red, column: 8, row: 31, string: "CONFIGURATION")
background.print(0, color: .White, column: 4, row: 26, string: "OPERATION")
background.print(0, color: .White, column: 4, row: 21, string: "EXTRA MODE")
background.print(0, color: .White, column: 4, row: 16, string: "DEBUG MODE")
background.print(0, color: .White, column: 4, row: 11, string: "LANGUAGE")
background.print(0, color: .White, column: 4, row: 6, string: "SETTING")
print_operation(color: .Pink)
print_extraMode(color: .Pink)
print_debugMode(color: .Pink)
print_language(color: .Pink)
print_resetSetting(color: .Pink)
goToNextSequence()
case 4:
// wait for event
break;
case 5: // operation
context.operationMode = context.operationMode.getNext()
print_operation(color: .Yellow)
goToNextSequence(4)
case 6: // ExtraMode/
context.extraMode = context.extraMode.getNext()
print_extraMode(color: .Yellow)
goToNextSequence(4)
case 7: // DebugMode
context.debugMode = context.debugMode.getNext()
print_debugMode(color: .Yellow)
goToNextSequence(4)
case 8: // Language
context.language = context.language.getNext()
print_language(color: .Yellow)
goToNextSequence(4)
case 9: // ResetSetting
context.resetSetting = context.resetSetting.getNext()
print_resetSetting(color: .Yellow)
goToNextSequence(4)
case 10:
context.saveConfiguration()
goToNextSequence(0)
default:
clear()
// Stop and exit running sequence.
return false
}
return true
}
func clear() {
background.fill(0, texture: 0)
}
func print_operation(color: CgCustomBackgroundManager.EnBgColor) {
let str = context.operationMode.getString()
background.print(0, color: color, column: 16, row: 26, string: str)
}
func print_extraMode(color: CgCustomBackgroundManager.EnBgColor) {
let str = context.extraMode.getString()
background.print(0, color: color, column: 16, row: 21, string: str)
}
func print_debugMode(color: CgCustomBackgroundManager.EnBgColor) {
let str = context.debugMode.getString()
background.print(0, color: color, column: 16, row: 16, string: str)
}
func print_language(color: CgCustomBackgroundManager.EnBgColor) {
let str = context.language.getString()
background.print(0, color: color, column: 16, row: 11, string: str)
}
func print_resetSetting(color: CgCustomBackgroundManager.EnBgColor) {
let str = context.resetSetting.getString()
background.print(0, color: color, column: 16, row: 6, string: str)
}
func search(column: Int, row: Int) -> EnEvent {
var event: EnEvent = .None
for i in 0 ..< table_search.count {
let t = table_search[i]
if (t.column0 <= column && t.row0 <= row) && (t.column1 >= column && t.row1 >= row) {
event = t.event
break
}
}
return event
}
}
Wenn ein Touch-Ereignis von der handelEvent-Methode empfangen wird, wird der von der Suchfunktion gedrückte Bereich überprüft und gegebenenfalls der Fall dieser Sequenz ausgeführt.
Der Einstellungswert wird in der CgContext-Klasse definiert.
class CgContext {
enum EnOperationMode: Int {
case Swipe = 0, Touch, Accel
func getString() -> String {
switch self {
case .Swipe: return "(SWIPE)"
case .Touch: return "(TOUCH)"
case .Accel: return "(ACCEL)"
}
}
func getNext() -> EnOperationMode {
switch self {
case .Swipe: return .Touch
case .Touch: return .Accel
case .Accel: return .Swipe
}
}
}
enum EnLanguage: Int {
case English = 0, Japanese
func getString() -> String {
switch self {
case .English: return "(ENGLISH) "
case .Japanese: return "(JAPANESE)"
}
}
func getNext() -> EnLanguage {
switch self {
case .English: return .Japanese
case .Japanese: return .English
}
}
}
enum EnOnOff: Int {
case Off = 0, On
func getString() -> String {
switch self {
case .On: return "(ON) "
case .Off: return "(OFF)"
}
}
func getNext() -> EnOnOff {
switch self {
case .On: return .Off
case .Off: return .On
}
}
}
enum EnSetting: Int {
case Clear = 0, Keep
func getString() -> String {
switch self {
case .Clear: return "(CLEAR)"
case .Keep: return "(KEEP) "
}
}
func getNext() -> EnSetting {
switch self {
case .Clear: return .Keep
case .Keep: return .Clear
}
}
}
var operationMode: EnOperationMode = .Swipe
var extraMode: EnOnOff = .Off
var debugMode: EnOnOff = .Off
var resetSetting: EnSetting = .Clear
var language: EnLanguage = .Japanese
//Unten weggelassen
class GameScene: SKScene {
/// Main object with main game sequence
private var gameMain: CgGameMain!
/// Points for Swipe operation
private var startPoint: CGPoint = CGPoint.init()
private var endPoint: CGPoint = CGPoint.init()
// MotionManager for accel
private var motionManager: CMMotionManager!
override func didMove(to view: SKView) {
// Create and start game sequence.
gameMain = CgGameMain(skscene: self)
gameMain.startSequence()
// Create motion manager
motionManager = CMMotionManager()
motionManager.accelerometerUpdateInterval = 0.05
motionManager.startAccelerometerUpdates(
to: OperationQueue.current!, withHandler: {
(accelData: CMAccelerometerData?, errorOC: Error?) in self.sendAccelEvent(acceleration: accelData!.acceleration)
}
)
}
func sendAccelEvent(acceleration: CMAcceleration){
let x_diff: Int = Int(acceleration.x * 100)
let y_diff: Int = Int(acceleration.y * 100)
if abs(x_diff) > abs(y_diff) {
gameMain.sendEvent(message: .Accel, parameter: [Int(x_diff > 0 ? EnDirection.Right.rawValue : EnDirection.Left.rawValue)])
} else {
gameMain.sendEvent(message: .Accel, parameter: [Int(y_diff > 0 ? EnDirection.Up.rawValue : EnDirection.Down.rawValue)])
}
}
Generieren Sie CMMotionManager in der GameScene-Klasse und legen Sie den Zyklus fest, um den Wert im AccelerometerUpdateInterval-Member abzurufen. Setzen Sie sendAccelEvent in der Rückrufmethode.
Die sendAccelEvent-Methode wird in einem Zyklus von 0,05 Sekunden aufgerufen, in dem die Richtung aus der Neigung des Beschleunigungssensors berechnet wird und das Ereignis mit gameMain.sendEvent auf dieselbe Weise wie die Wischoperation an das Objekt gesendet wird.
class CgPlayer : CgActor {
/// Event handler
/// - Parameters:
/// - sender: Message sender
/// - id: Message ID
/// - values: Parameters of message
override func handleEvent(sender: CbObject, message: EnMessage, parameter values: [Int]) {
guard !deligateActor.isDemoMode() else { return }
switch message {
case .Accel where deligateActor.isOperationMode(mode: CgContext.EnOperationMode.Accel): fallthrough
case .Swipe where deligateActor.isOperationMode(mode: CgContext.EnOperationMode.Swipe):
if let direction = EnDirection(rawValue: values[0]) {
targetDirecition = direction
}
case .Touch where deligateActor.isOperationMode(mode: CgContext.EnOperationMode.Touch):
setTargetPosition(x: values[0], y: values[1])
targetDirecition = decideDirectionByTarget(forcedDirectionChange: true)
position.amountMoved = 0
default:
break
}
}
Wenn die im Konfigurationsmenü festgelegte Operation in handleEvent der CgPlayer-Klasse (deligateActor.isOperationMode (Modus: CgContext.EnOperationMode.Accel)) gültig ist, wird das Ereignis des Beschleunigungssensors akzeptiert.
Informationen hierzu finden Sie in der vorherigen [Einführung] iOS App Development # 6 [Character Operation].
Lassen Sie die getMazeSource-Methode der CgSceneMaze-Klasse die Labyrinthdaten um den Wert des Menüs ändern. Das Erstellen dieser Labyrinthdaten ist klassisch, aber überraschend einfach.
func getMazeSource() -> [String] {
let mazeSource: [String] = [
"aggggggggggggjiggggggggggggb",
"e111111111111EF111111111111f",
"e1AGGB1AGGGB1EF1AGGGB1AGGB1f",
"e3E F1E F1EF1E F1E F3f",
"e1CHHD1CHHHD1CD1CHHHD1CHHD1f",
"e11111111111111111111111111f",
"e1AGGB1AB1AGGGGGGB1AB1AGGB1f",
"e1CHHD1EF1CHHJIHHD1EF1CHHD1f",
"e111111EF1111EF1111EF111111f",
"chhhhB1EKGGB1EF1AGGLF1Ahhhhd",
" e1EIHHD2CD2CHHJF1f ",
" e1EF EF1f ",
" e1EF QhUWWVhR EF1f ",
"gggggD1CD f e CD1Cggggg",
"____ 1 f e 1 ____" ,
"hhhhhB1AB f e AB1Ahhhhh",
" e1EF SggggggT EF1f ",
" e1EF EF1f ",
" e1EF AGGGGGGB EF1f ",
"aggggD1CD1CHHJIHHD1CD1Cggggb",
"e111111111111EF111111111111f",
"e1AGGB1AGGGB1EF1AGGGB1AGGB1f",
"e1CHJF1CHHHD2CD2CHHHD1EIHD1f",
"e311EF1111111 1111111EF113f",
"kGB1EF1AB1AGGGGGGB1AB1EF1AGl",
"YHD1CD1EF1CHHJIHHD1EF1CD1CHZ",
"e111111EF1111EF1111EF111111f",
"e1AGGGGLKGGB1EF1AGGLKGGGGB1f",
"e1CHHHHHHHHD1CD1CHHHHHHHHD1f",
"e11111111111111111111111111f",
"chhhhhhhhhhhhhhhhhhhhhhhhhhd"
]
let mazeSourceExtra1: [String] = [
"aggggjiggggggjiggggggjiggggb",
"e1111EF111111EF111111EF1111f",
"e1AB1EF1AGGB1CD1AGGB1EF1AB1f",
"e3EF1EF1E F1111E F1EF1EF3f",
"e1CD1CD1CHHD1AB1CHHD1CD1CD1f",
"e111111111111EF111111111111f",
"kGGB1AGGB1AGGLKGGB1AGGB1AGGl",
"YHJF1EIHD1CHHJIHHD1CHJF1EIHZ",
"e1EF1EF111111EF111111EF1EF1f",
"e1EF1EKGGGGB1EF1AGGGGLF1EF1f",
"e1CD1CHHHHHD2CD2CHHHHHD1CD1f",
"e11111111 11111111f",
"e1AB1AGGB QhUWWVhR AGGB1AB1f",
"e1EF1CHHD f e CHHD1EF1f",
"e1EF11111 f e 11111EF1f",
"kGLF1AGGB f e AGGB1EKGl",
"YHHD1EIHD SggggggT CHJF1CHHZ",
"e1111EF11 11EF1111f",
"e1AGGLF1AGGGGGGGGGGB1EKGGB1f",
"e1CHHJF1CHHHHJIHHHHD1EIHHD1f",
"e1111EF111111EF111111EF1111f",
"kGGB1EKGGGGB1EF1AGGGGLF1AGGl",
"YHHD1CHHHHHD2CD2CHHHHHD1CHHZ",
"e111111111111 111111111111f",
"e1AGGGB1AGGGGGGGGGGB1AGGGB1f",
"e1CHHJF1CHHHHJIHHHHD1EIHHD1f",
"e3111EF111111EF111111EF1113f",
"kGGB1EF1AB1AGLKGB1AB1EF1AGGl",
"YHHD1CD1EF1CHHHHD1EF1CD1CHHZ",
"e1111111EF11111111EF1111111f",
"chhhhhhhnmhhhhhhhhnmhhhhhhhd"
]
return context.extraMode == CgContext.EnOnOff.Off ? mazeSource : mazeSourceExtra1
}
Das Folgende wurde dieses Mal als Arrangement des Pacman-Spiels hinzugefügt. --Konfigurationsmenü
Ich habe mit Swift iOS-Programmierung basierend auf Pacmans Spielen studiert. Der Quellcode bestand aus etwa 5000 Zeilen einschließlich Kommentaren, und es war leicht möglich, die Qualität und Anordnung eines Arcade-Spiels zu realisieren.
Es begann mit einem Sommerurlaub, in dem ich in Corona nirgendwo hingehen konnte, aber es war eine weitere gute Gelegenheit, das Programmieren zu genießen.
Dies ist das Ende aller 11 Einführungen in die Entwicklung von iOS-Anwendungen.
Danke fürs Lesen ~
Recommended Posts