Skip to content

Commit

Permalink
Merge pull request #40 from cs3217-2324/minimap
Browse files Browse the repository at this point in the history
Feat/Minimap
  • Loading branch information
ruihan00 committed Mar 28, 2024
2 parents 5794b02 + b025170 commit 5aca934
Show file tree
Hide file tree
Showing 21 changed files with 188 additions and 20 deletions.
Expand Up @@ -6,7 +6,6 @@ public class SDPhysicsBody {
public init(rectangleOf size: CGSize) {
body = SKPhysicsBody(rectangleOf: size)
body.friction = 0
body.linearDamping = 0
body.restitution = 0
}

Expand Down
8 changes: 8 additions & 0 deletions star-dash/star-dash.xcodeproj/project.pbxproj
Expand Up @@ -55,6 +55,8 @@
46D418242BA5D5280091A38B /* Tool+Collidable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46D418232BA5D5280091A38B /* Tool+Collidable.swift */; };
46D418262BA5D6500091A38B /* Wall+Collidable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46D418252BA5D6500091A38B /* Wall+Collidable.swift */; };
46D418282BA5D6800091A38B /* Floor+Collidable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46D418272BA5D6800091A38B /* Floor+Collidable.swift */; };
4E0905FD2BB4A15600DE666B /* MiniMapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E0905FC2BB4A15600DE666B /* MiniMapView.swift */; };
4E0905FF2BB4A4EB00DE666B /* PlayerInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E0905FE2BB4A4EB00DE666B /* PlayerInfo.swift */; };
4E3458DF2BA7490B00E817C6 /* EntityManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E3458DE2BA7490B00E817C6 /* EntityManagerTests.swift */; };
4E3458E52BA75E6800E817C6 /* PositionComponentTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E3458E42BA75E6800E817C6 /* PositionComponentTests.swift */; };
4E3458E72BA75E7100E817C6 /* HealthComponentTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E3458E62BA75E7100E817C6 /* HealthComponentTests.swift */; };
Expand Down Expand Up @@ -205,6 +207,8 @@
46D418232BA5D5280091A38B /* Tool+Collidable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Tool+Collidable.swift"; sourceTree = "<group>"; };
46D418252BA5D6500091A38B /* Wall+Collidable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Wall+Collidable.swift"; sourceTree = "<group>"; };
46D418272BA5D6800091A38B /* Floor+Collidable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Floor+Collidable.swift"; sourceTree = "<group>"; };
4E0905FC2BB4A15600DE666B /* MiniMapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MiniMapView.swift; sourceTree = "<group>"; };
4E0905FE2BB4A4EB00DE666B /* PlayerInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerInfo.swift; sourceTree = "<group>"; };
4E3458DE2BA7490B00E817C6 /* EntityManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EntityManagerTests.swift; sourceTree = "<group>"; };
4E3458E42BA75E6800E817C6 /* PositionComponentTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PositionComponentTests.swift; sourceTree = "<group>"; };
4E3458E62BA75E7100E817C6 /* HealthComponentTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HealthComponentTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -423,6 +427,7 @@
4E630F252B9F7E500008F887 /* Entities */,
46B8C0992BA328D900498705 /* GameEngine.swift */,
E69EE9312BAC6CBB00033AB5 /* GameInfo.swift */,
4E0905FE2BB4A4EB00DE666B /* PlayerInfo.swift */,
);
path = GameEngine;
sourceTree = "<group>";
Expand Down Expand Up @@ -668,6 +673,7 @@
E6A7451C2BA0CAD90080C1BE /* JoystickView.swift */,
E6A745122BA057040080C1BE /* ControlView.swift */,
E6B550A02BA15E9C00DC7396 /* OverlayView.swift */,
4E0905FC2BB4A15600DE666B /* MiniMapView.swift */,
);
path = MTKRenderer;
sourceTree = "<group>";
Expand Down Expand Up @@ -862,11 +868,13 @@
46D4181A2BA5CDBD0091A38B /* CollisionHandler.swift in Sources */,
4E86605F2BA095E30035530D /* Collectible.swift in Sources */,
E64361122BA4C2CD003850FD /* ObjectModule.swift in Sources */,
4E0905FF2BB4A4EB00DE666B /* PlayerInfo.swift in Sources */,
4E59E2532BAB3061007B3FA7 /* Database.swift in Sources */,
4E8660662BA097D40035530D /* PhysicsConstants.swift in Sources */,
143AA3952BA4DF1C009C28E7 /* MonsterAttackPlayerEvent.swift in Sources */,
143AA3932BA4DBE7009C28E7 /* PlayerMonsterContactEvent.swift in Sources */,
4E59E2682BADA7B6007B3FA7 /* CollectibleEntityPersistable.swift in Sources */,
4E0905FD2BB4A15600DE666B /* MiniMapView.swift in Sources */,
46D418162BA5CBD60091A38B /* Collidable.swift in Sources */,
461148912BA1CDBF0073E7E1 /* SystemManager.swift in Sources */,
460A20112BB1E6DF002597B8 /* MonsterSystem.swift in Sources */,
Expand Down
21 changes: 21 additions & 0 deletions star-dash/star-dash/Assets.xcassets/MiniMap.imageset/Contents.json
@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "Star dash-15.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions star-dash/star-dash/Assets.xcassets/PlayerIcons/Contents.json
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "Idle (10) copy.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 6 additions & 2 deletions star-dash/star-dash/Constants/PhysicsConstants.swift
Expand Up @@ -51,7 +51,11 @@ struct PhysicsConstants {
static let floor = CGSize(width: 300, height: 60)
}

static let jumpImpulse = CGVector(dx: 15, dy: 250)
static let runVelocity = CGVector(dx: 15, dy: 0)
struct Mass {
static let player = CGFloat(50)
}

static let jumpImpulse = CGVector(dx: 15, dy: 7_500)
static let runVelocity = CGVector(dx: 200, dy: 0)
static let maxRunVelocity = CGVector(dx: 250, dy: 0)
}
2 changes: 2 additions & 0 deletions star-dash/star-dash/GameBridge/SyncModule/PhysicsModule.swift
Expand Up @@ -27,6 +27,7 @@ class PhysicsModule: SyncModule {

body.mass = physicsComponent.mass
body.velocity = physicsComponent.velocity

// body.force = physicsComponent.force
}

Expand All @@ -42,6 +43,7 @@ class PhysicsModule: SyncModule {
object.physicsBody?.categoryBitMask = physicsComponent.categoryBitMask
object.physicsBody?.contactTestMask = physicsComponent.contactTestMask
object.physicsBody?.collisionBitMask = physicsComponent.collisionBitMask
object.physicsBody?.mass = physicsComponent.mass
}

private func createRectanglePhysicsBody(physicsComponent: PhysicsComponent) -> SDPhysicsBody {
Expand Down
Expand Up @@ -9,7 +9,7 @@ import Foundation

class PhysicsComponent: Component {
var shape: Shape
var mass: CGFloat = .zero
var mass = CGFloat(10)
var velocity: CGVector = .zero
var force: CGVector = .zero
var categoryBitMask: UInt32 = 0xFFFFFFFF
Expand Down
16 changes: 15 additions & 1 deletion star-dash/star-dash/GameEngine/GameEngine.swift
Expand Up @@ -28,10 +28,24 @@ class GameEngine {
}

return GameInfo(
playerScore: score
playerScore: score,
playersInfo: playersInfo()
)
}

func playersInfo() -> [PlayerInfo] {
guard let playerEntityId = entityManager.playerEntityId(),
let positionSystem = systemManager.system(ofType: PositionSystem.self) else {
return []
}
var playersInfo = [PlayerInfo]()
if let position = positionSystem.getPosition(of: playerEntityId) {
playersInfo.append(PlayerInfo(position: position, player: .RedNose))
}
return playersInfo

}

func update(by deltaTime: TimeInterval) {
systemManager.update(by: deltaTime)
eventManager.executeAll(on: self)
Expand Down
1 change: 1 addition & 0 deletions star-dash/star-dash/GameEngine/GameInfo.swift
@@ -1,3 +1,4 @@
struct GameInfo {
let playerScore: Int
let playersInfo: [PlayerInfo]
}
13 changes: 13 additions & 0 deletions star-dash/star-dash/GameEngine/PlayerInfo.swift
@@ -0,0 +1,13 @@
//
// PlayerInfo.swift
// star-dash
//
// Created by Lau Rui han on 28/3/24.
//

import Foundation

struct PlayerInfo {
let position: CGPoint
let player: PlayerSprite
}
6 changes: 4 additions & 2 deletions star-dash/star-dash/GameEngine/Systems/CollisionSystem.swift
Expand Up @@ -99,10 +99,12 @@ class CollisionSystem: System {
let obstaclePositionComponent = entityManager.component(ofType: PositionComponent.self,
of: event.obstacleId),
let playerComponent = entityManager.component(ofType: PlayerComponent.self, of: event.playerId),
playerPositionComponent.position.y > obstaclePositionComponent.position.y else {
playerPositionComponent.position.y - PhysicsConstants.Dimensions.player.height / 2 >
obstaclePositionComponent.position.y + PhysicsConstants.Dimensions.obstacle.height / 2 else {
dispatcher?.add(event: StopMovingEvent(on: event.playerId))

return
}

playerComponent.canJump = true
playerComponent.canMove = true
}
Expand Down
2 changes: 0 additions & 2 deletions star-dash/star-dash/GameEngine/Systems/PhysicsSystem.swift
Expand Up @@ -96,7 +96,6 @@ class PhysicsSystem: System {
}
playerComponent.canJump = false
playerComponent.canMove = false

applyImpulse(to: event.entityId, impulse: event.jumpImpulse)
}

Expand All @@ -105,7 +104,6 @@ class PhysicsSystem: System {
let spriteComponent = entityManager.component(ofType: SpriteComponent.self, of: event.entityId) else {
return
}

physicsComponent.velocity = .zero
spriteComponent.textureAtlas = nil
}
Expand Down
24 changes: 16 additions & 8 deletions star-dash/star-dash/Rendering/MTKRenderer/ControlView.swift
Expand Up @@ -4,7 +4,7 @@ import UIKit
`ControlView` is responsible for displaying the controls
such as jump button and joystick.
*/
class ControlView: UIView {
class ControlView: UIView, UIGestureRecognizerDelegate {

var joystickView: JoystickView?

Expand Down Expand Up @@ -54,7 +54,7 @@ class ControlView: UIView {
private func setupGestureRecognizers() {
let panGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePan(_:)))
panGesture.cancelsTouchesInView = false

panGesture.delegate = self
addGestureRecognizer(panGesture)
}

Expand Down Expand Up @@ -96,6 +96,16 @@ class ControlView: UIView {
controlViewDelegate?.joystickReleased()
joystickView?.returnJoystick()
}
// To ensure gesture recognise only in a specific area
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
let touchLocation = touch.location(in: self)
let halfScreenWidth = self.frame.width / 2
let ignoredAreaRect = CGRect(x: halfScreenWidth, y: 0, width: halfScreenWidth, height: self.frame.height)
if ignoredAreaRect.contains(touchLocation) {
return false
}
return true
}

@objc
func handlePan(_ gesture: UIPanGestureRecognizer) {
Expand All @@ -110,12 +120,10 @@ class ControlView: UIView {
return
}

if location.x < self.frame.width / 2 {
joystickView.moveJoystick(location: gesture.location(in: joystickView))
if shouldSendMoveEvent(location: location) {
let isLeft = gesture.location(in: joystickView).x < joystickView.center.x
controlViewDelegate?.joystickMoved(toLeft: isLeft)
}
joystickView.moveJoystick(location: gesture.location(in: joystickView))
if shouldSendMoveEvent(location: location) {
let isLeft = gesture.location(in: joystickView).x < joystickView.center.x
controlViewDelegate?.joystickMoved(toLeft: isLeft)
}
}

Expand Down
Expand Up @@ -37,6 +37,7 @@ class MTKRenderer: NSObject, Renderer {

func updateOverlay(overlayInfo: OverlayInfo) {
playerView?.updateOverlay(score: overlayInfo.score)
playerView?.updateMinimap(playersInfo: overlayInfo.playersInfo)
}

/// Set ups the views for a single player game.
Expand Down
62 changes: 62 additions & 0 deletions star-dash/star-dash/Rendering/MTKRenderer/MiniMapView.swift
@@ -0,0 +1,62 @@
//
// MiniMapView.swift
// star-dash
//
// Created by Lau Rui han on 28/3/24.
//

import Foundation
import UIKit

class MiniMapView: UIView {
// Player number label
private var mapImageView: UIImageView!
private var playerIcons: [UIImageView] = []
override init(frame: CGRect) {
super.init(frame: frame)
}

required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}

func setupSubviews() {
mapImageView = UIImageView(image: UIImage(named: "MiniMap"))

Check failure on line 24 in star-dash/star-dash/Rendering/MTKRenderer/MiniMapView.swift

View workflow job for this annotation

GitHub Actions / build

Prefer object literals over image and color inits. (object_literal)
mapImageView.contentMode = .scaleAspectFit
mapImageView.translatesAutoresizingMaskIntoConstraints = false
addSubview(mapImageView)

NSLayoutConstraint.activate([
mapImageView.topAnchor.constraint(equalTo: topAnchor, constant: 50),
mapImageView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 30),
mapImageView.widthAnchor.constraint(equalToConstant: 300),
mapImageView.heightAnchor.constraint(equalToConstant: 50)
])
}
// TODO: Pass in actual map size
func update(playersInfo: [PlayerInfo], mapSize: CGSize = CGSize(width: 4_500, height: 0)) {
removeAllPlayerIcons()

for playerData in playersInfo {
let playerIcon = UIImageView(image: UIImage(named: "RedNoseIcon"))

Check failure on line 41 in star-dash/star-dash/Rendering/MTKRenderer/MiniMapView.swift

View workflow job for this annotation

GitHub Actions / build

Prefer object literals over image and color inits. (object_literal)
playerIcon.contentMode = .scaleAspectFit
playerIcon.translatesAutoresizingMaskIntoConstraints = false
addSubview(playerIcon)
playerIcons.append(playerIcon)

let miniMapX = (playerData.position.x / mapSize.width) * mapImageView.frame.width

playerIcon.widthAnchor.constraint(equalToConstant: 30).isActive = true
playerIcon.centerXAnchor.constraint(equalTo: mapImageView.leadingAnchor, constant: miniMapX).isActive = true
playerIcon.centerYAnchor.constraint(equalTo: mapImageView.bottomAnchor, constant: -20).isActive = true
}
}

private func removeAllPlayerIcons() {
for playerIcon in playerIcons {
playerIcon.removeFromSuperview()
}
playerIcons.removeAll()
}

}
9 changes: 8 additions & 1 deletion star-dash/star-dash/Rendering/MTKRenderer/PlayerView.swift
Expand Up @@ -14,14 +14,16 @@ class PlayerView {
var sceneView: MTKView
var controlView: ControlView
var overlayView: OverlayView

var miniMapView: MiniMapView
init(superview: UIView, device: MTLDevice, drawDelegate: MTKViewDelegate) {
self.sceneView = MTKView(frame: superview.frame, device: device)
self.sceneView.delegate = drawDelegate
superview.addSubview(self.sceneView)

self.overlayView = OverlayView(frame: superview.frame)
superview.addSubview(self.overlayView)
self.miniMapView = MiniMapView(frame: superview.frame)
superview.addSubview(self.miniMapView)

self.controlView = ControlView(frame: superview.frame)
superview.addSubview(self.controlView)
Expand All @@ -30,6 +32,7 @@ class PlayerView {
func setupSubviews() {
self.controlView.setupSubviews()
self.overlayView.setupSubviews()
self.miniMapView.setupSubviews()
}

func setControlViewDelegate(_ delegate: ControlViewDelegate) {
Expand All @@ -39,4 +42,8 @@ class PlayerView {
func updateOverlay(score: Int) {
overlayView.update(score: score)
}

func updateMinimap(playersInfo: [PlayerInfo]) {
miniMapView.update(playersInfo: playersInfo)
}
}
1 change: 1 addition & 0 deletions star-dash/star-dash/Rendering/OverlayInfo.swift
@@ -1,3 +1,4 @@
struct OverlayInfo {
let score: Int
let playersInfo: [PlayerInfo]
}
4 changes: 2 additions & 2 deletions star-dash/star-dash/ViewController.swift
Expand Up @@ -98,9 +98,9 @@ extension ViewController: SDSceneDelegate {
guard let gameInfo = gameEngine?.gameInfo() else {
return
}

renderer?.updateOverlay(overlayInfo: OverlayInfo(
score: gameInfo.playerScore
score: gameInfo.playerScore,
playersInfo: gameInfo.playersInfo
))
}

Expand Down

0 comments on commit 5aca934

Please sign in to comment.