removed iOS example project
This commit is contained in:
parent
202a35833e
commit
bb8ab464d0
|
|
@ -1,62 +0,0 @@
|
||||||
cmake_minimum_required(VERSION 3.25)
|
|
||||||
|
|
||||||
project(raylib_ios_example LANGUAGES C OBJC)
|
|
||||||
|
|
||||||
set(raylib_ios_example_sources
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/main.c
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/../../src/rcore.c
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/../../src/rmodels.c
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/../../src/rshapes.c
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/../../src/rtext.c
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/../../src/rtextures.c
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/../../src/rcore_ios_main.m
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/../../logo/raylib_1024x1024.png
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/../../logo/raylib_512x512.png
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/../../logo/raylib_180x180.png
|
|
||||||
)
|
|
||||||
|
|
||||||
find_library(UIKIT_LIBRARY UIKit)
|
|
||||||
find_library(QUARTZCORE_LIBRARY QuartzCore)
|
|
||||||
find_library(OPENGLES_LIBRARY OpenGLES)
|
|
||||||
find_library(COREMOTION_LIBRARY CoreMotion)
|
|
||||||
find_library(FOUNDATION_LIBRARY Foundation)
|
|
||||||
|
|
||||||
add_executable(raylib-ios-example MACOSX_BUNDLE ${raylib_ios_example_sources})
|
|
||||||
|
|
||||||
target_include_directories(raylib-ios-example PRIVATE
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/../../src
|
|
||||||
)
|
|
||||||
|
|
||||||
target_compile_definitions(raylib-ios-example PRIVATE
|
|
||||||
PLATFORM_IOS
|
|
||||||
GRAPHICS_API_OPENGL_ES3
|
|
||||||
SUPPORT_MODULE_RAUDIO=0 # FIXME: Currently the mini_audio backend is not working on iOS, so we disable audio support for this example
|
|
||||||
GLES_SILENCE_DEPRECATION=1
|
|
||||||
)
|
|
||||||
|
|
||||||
target_compile_options(raylib-ios-example PRIVATE -Wno-deprecated-declarations)
|
|
||||||
|
|
||||||
set_source_files_properties(
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/../../logo/raylib_1024x1024.png
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/../../logo/raylib_512x512.png
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/../../logo/raylib_180x180.png
|
|
||||||
PROPERTIES MACOSX_PACKAGE_LOCATION Resources
|
|
||||||
)
|
|
||||||
|
|
||||||
target_link_libraries(raylib-ios-example PRIVATE
|
|
||||||
${UIKIT_LIBRARY}
|
|
||||||
${QUARTZCORE_LIBRARY}
|
|
||||||
${OPENGLES_LIBRARY}
|
|
||||||
${COREMOTION_LIBRARY}
|
|
||||||
${FOUNDATION_LIBRARY}
|
|
||||||
)
|
|
||||||
|
|
||||||
set_target_properties(raylib-ios-example PROPERTIES
|
|
||||||
MACOSX_BUNDLE TRUE
|
|
||||||
MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_LIST_DIR}/Info.plist"
|
|
||||||
XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC "YES"
|
|
||||||
XCODE_ATTRIBUTE_GENERATE_INFOPLIST_FILE "NO"
|
|
||||||
XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET "13.0"
|
|
||||||
XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER "com.raylib.raylib-ios-example"
|
|
||||||
XCODE_ATTRIBUTE_TARGETED_DEVICE_FAMILY "1,2"
|
|
||||||
)
|
|
||||||
|
|
@ -1,79 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
||||||
<plist version="1.0">
|
|
||||||
<dict>
|
|
||||||
<key>CFBundleDevelopmentRegion</key>
|
|
||||||
<string>en</string>
|
|
||||||
<key>CFBundleDisplayName</key>
|
|
||||||
<string>raylib iOS Example</string>
|
|
||||||
<key>CFBundleExecutable</key>
|
|
||||||
<string>$(EXECUTABLE_NAME)</string>
|
|
||||||
<key>CFBundleIdentifier</key>
|
|
||||||
<string>com.raylib.raylib-ios-example</string>
|
|
||||||
<key>CFBundleInfoDictionaryVersion</key>
|
|
||||||
<string>6.0</string>
|
|
||||||
<key>CFBundleName</key>
|
|
||||||
<string>raylib-ios-example</string>
|
|
||||||
<key>CFBundlePackageType</key>
|
|
||||||
<string>APPL</string>
|
|
||||||
<key>CFBundleShortVersionString</key>
|
|
||||||
<string>1.0</string>
|
|
||||||
<key>CFBundleVersion</key>
|
|
||||||
<string>1</string>
|
|
||||||
<key>LSRequiresIPhoneOS</key>
|
|
||||||
<true/>
|
|
||||||
<key>CFBundleIcons</key>
|
|
||||||
<dict>
|
|
||||||
<key>CFBundlePrimaryIcon</key>
|
|
||||||
<dict>
|
|
||||||
<key>CFBundleIconFiles</key>
|
|
||||||
<array>
|
|
||||||
<string>raylib_180x180</string>
|
|
||||||
<string>raylib_512x512</string>
|
|
||||||
<string>raylib_1024x1024</string>
|
|
||||||
</array>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<key>CFBundleIcons~ipad</key>
|
|
||||||
<dict>
|
|
||||||
<key>CFBundlePrimaryIcon</key>
|
|
||||||
<dict>
|
|
||||||
<key>CFBundleIconFiles</key>
|
|
||||||
<array>
|
|
||||||
<string>raylib_180x180</string>
|
|
||||||
<string>raylib_512x512</string>
|
|
||||||
<string>raylib_1024x1024</string>
|
|
||||||
</array>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<key>UIRequiredDeviceCapabilities</key>
|
|
||||||
<array>
|
|
||||||
<string>opengles-3</string>
|
|
||||||
</array>
|
|
||||||
<key>UIApplicationSceneManifest</key>
|
|
||||||
<dict>
|
|
||||||
<key>UIApplicationSupportsMultipleScenes</key>
|
|
||||||
<false/>
|
|
||||||
<key>UISceneConfigurations</key>
|
|
||||||
<dict>
|
|
||||||
<key>UIWindowSceneSessionRoleApplication</key>
|
|
||||||
<array>
|
|
||||||
<dict>
|
|
||||||
<key>UISceneConfigurationName</key>
|
|
||||||
<string>Default Configuration</string>
|
|
||||||
<key>UISceneDelegateClassName</key>
|
|
||||||
<string>RaylibSceneDelegate</string>
|
|
||||||
<key>UISceneClassName</key>
|
|
||||||
<string>UIWindowScene</string>
|
|
||||||
</dict>
|
|
||||||
</array>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<key>UISupportedInterfaceOrientations</key>
|
|
||||||
<array>
|
|
||||||
<string>UIInterfaceOrientationPortrait</string>
|
|
||||||
<!-- <string>UIInterfaceOrientationLandscapeLeft</string> -->
|
|
||||||
<!-- <string>UIInterfaceOrientationLandscapeRight</string> -->
|
|
||||||
</array>
|
|
||||||
</dict>
|
|
||||||
</plist>
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
||||||
# raylib Breakout demo
|
|
||||||
|
|
||||||
This example is generated with CMake and opened in Xcode. Use the simulator or a real device by changing the Apple SDK you target.
|
|
||||||
|
|
||||||
## Requirements
|
|
||||||
|
|
||||||
- macOS with Xcode installed
|
|
||||||
- CMake 3.18 or newer
|
|
||||||
- iOS Simulator support from Xcode, or a connected iPhone/iPad for device testing
|
|
||||||
- An Apple developer signing team if you want to run on a real device
|
|
||||||
- Min. iOS API 13
|
|
||||||
|
|
||||||
## Generate the Xcode project
|
|
||||||
|
|
||||||
From this folder, run:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
cmake -S . -B build -G Xcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_SYSROOT=iphonesimulator
|
|
||||||
```
|
|
||||||
|
|
||||||
This generates `build/raylib_ios_example.xcodeproj`.
|
|
||||||
|
|
||||||
## Run in the iOS Simulator
|
|
||||||
|
|
||||||
1. Open `build/raylib_ios_example.xcodeproj` in Xcode.
|
|
||||||
2. Select an iPhone Simulator destination.
|
|
||||||
3. Build and run the `raylib-ios-example` scheme.
|
|
||||||
|
|
||||||
## Run on a real iPhone or iPad
|
|
||||||
|
|
||||||
1. Regenerate the project for the device SDK:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
cmake -S . -B build -G Xcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_SYSROOT=iphoneos
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Open the generated Xcode project.
|
|
||||||
3. Select your connected device.
|
|
||||||
4. Set a valid signing team in Xcode if needed.
|
|
||||||
5. Build and run the same `raylib-ios-example` scheme.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,433 +0,0 @@
|
||||||
#include "raylib.h"
|
|
||||||
#include "raymath.h"
|
|
||||||
|
|
||||||
#define BRICK_ROWS 5
|
|
||||||
#define BRICK_COLS 7
|
|
||||||
#define BRICK_PADDING 6.0f
|
|
||||||
#define BALL_SPEED_INIT 500.0f
|
|
||||||
#define BALL_SPEED_MAX 900.0f
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
STATE_TITLE,
|
|
||||||
STATE_PLAYING,
|
|
||||||
STATE_PAUSED,
|
|
||||||
STATE_WIN,
|
|
||||||
STATE_LOSE,
|
|
||||||
} GameState;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
Rectangle rect;
|
|
||||||
Color color;
|
|
||||||
bool alive;
|
|
||||||
int points;
|
|
||||||
} Brick;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
Color background;
|
|
||||||
Color panel;
|
|
||||||
Color panelBorder;
|
|
||||||
Color accent;
|
|
||||||
Color accentBorder;
|
|
||||||
Color text;
|
|
||||||
Color muted;
|
|
||||||
Color shadow;
|
|
||||||
|
|
||||||
float margin;
|
|
||||||
float topBarHeight;
|
|
||||||
float buttonWidth;
|
|
||||||
float buttonHeight;
|
|
||||||
float actionWidth;
|
|
||||||
float actionHeight;
|
|
||||||
float roundness;
|
|
||||||
} UITheme;
|
|
||||||
|
|
||||||
static UITheme DefaultUITheme(void) {
|
|
||||||
return (UITheme){
|
|
||||||
.background = {14, 16, 22, 255},
|
|
||||||
.panel = {245, 245, 245, 255},
|
|
||||||
.panelBorder = {245, 245, 245, 255},
|
|
||||||
.accent = {60, 180, 255, 255},
|
|
||||||
.accentBorder = {245, 245, 245, 255},
|
|
||||||
.text = {20, 20, 24, 255},
|
|
||||||
.muted = {160, 170, 190, 255},
|
|
||||||
.shadow = {0, 0, 0, 160},
|
|
||||||
|
|
||||||
.margin = 12.0f,
|
|
||||||
.topBarHeight = 34.0f,
|
|
||||||
.buttonWidth = 104.0f,
|
|
||||||
.buttonHeight = 34.0f,
|
|
||||||
.actionWidth = 168.0f,
|
|
||||||
.actionHeight = 36.0f,
|
|
||||||
.roundness = 0.0f,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
static Color BrickColor(int row) {
|
|
||||||
Color palette[] = {
|
|
||||||
{255, 80, 80, 255}, {255, 160, 40, 255}, {255, 220, 40, 255},
|
|
||||||
{80, 210, 90, 255}, {60, 180, 255, 255},
|
|
||||||
};
|
|
||||||
return palette[row % 5];
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool CollideBallRect(Vector2 *pos, Vector2 *vel, float radius,
|
|
||||||
Rectangle rect, float dt) {
|
|
||||||
Rectangle expanded = {
|
|
||||||
rect.x - radius,
|
|
||||||
rect.y - radius,
|
|
||||||
rect.width + radius * 2.0f,
|
|
||||||
rect.height + radius * 2.0f,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!CheckCollisionPointRec(*pos, expanded))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
float nearX = Clamp(pos->x, rect.x, rect.x + rect.width);
|
|
||||||
float nearY = Clamp(pos->y, rect.y, rect.y + rect.height);
|
|
||||||
float dx = pos->x - nearX;
|
|
||||||
float dy = pos->y - nearY;
|
|
||||||
|
|
||||||
if (fabsf(dx) > fabsf(dy))
|
|
||||||
vel->x = -vel->x;
|
|
||||||
else
|
|
||||||
vel->y = -vel->y;
|
|
||||||
|
|
||||||
pos->x += vel->x * dt;
|
|
||||||
pos->y += vel->y * dt;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void BuildBricks(Brick bricks[BRICK_ROWS][BRICK_COLS], float sw,
|
|
||||||
float brickAreaTop, float brickAreaH) {
|
|
||||||
float brickW = (sw - BRICK_PADDING * (BRICK_COLS + 1)) / BRICK_COLS;
|
|
||||||
float brickH = (brickAreaH - BRICK_PADDING * (BRICK_ROWS + 1)) / BRICK_ROWS;
|
|
||||||
|
|
||||||
for (int r = 0; r < BRICK_ROWS; r++) {
|
|
||||||
for (int c = 0; c < BRICK_COLS; c++) {
|
|
||||||
float bx = BRICK_PADDING + c * (brickW + BRICK_PADDING);
|
|
||||||
float by = brickAreaTop + BRICK_PADDING + r * (brickH + BRICK_PADDING);
|
|
||||||
bricks[r][c] = (Brick){
|
|
||||||
.rect = {bx, by, brickW, brickH},
|
|
||||||
.color = BrickColor(r),
|
|
||||||
.alive = true,
|
|
||||||
.points = (BRICK_ROWS - r) * 10,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
InitWindow(0, 0, "Breakout - raylib iOS");
|
|
||||||
SetTargetFPS(60);
|
|
||||||
|
|
||||||
UITheme ui = DefaultUITheme();
|
|
||||||
|
|
||||||
const char *logoPath =
|
|
||||||
TextFormat("%sraylib_180x180.png", GetApplicationDirectory());
|
|
||||||
Texture2D logo = LoadTexture(logoPath);
|
|
||||||
|
|
||||||
int sw = GetScreenWidth();
|
|
||||||
int sh = GetScreenHeight();
|
|
||||||
|
|
||||||
float paddleW = sw * 0.22f;
|
|
||||||
float paddleH = sh * 0.022f;
|
|
||||||
float paddleY = sh - sh * 0.10f;
|
|
||||||
float ballRadius = sw * 0.022f;
|
|
||||||
float brickAreaTop = sh * 0.22f;
|
|
||||||
float brickAreaH = sh * 0.32f;
|
|
||||||
|
|
||||||
GameState state = STATE_TITLE;
|
|
||||||
int score = 0;
|
|
||||||
int lives = 3;
|
|
||||||
int totalBricks = BRICK_ROWS * BRICK_COLS;
|
|
||||||
int aliveBricks = totalBricks;
|
|
||||||
|
|
||||||
Rectangle paddle = {sw * 0.5f - paddleW * 0.5f, paddleY, paddleW, paddleH};
|
|
||||||
Vector2 ball = {sw * 0.5f, paddleY - ballRadius - 2.0f};
|
|
||||||
Vector2 ballV = {BALL_SPEED_INIT * 0.6f, -BALL_SPEED_INIT};
|
|
||||||
bool ballLaunched = false;
|
|
||||||
|
|
||||||
Brick bricks[BRICK_ROWS][BRICK_COLS];
|
|
||||||
BuildBricks(bricks, (float)sw, brickAreaTop, brickAreaH);
|
|
||||||
|
|
||||||
#define RESET_BALL() \
|
|
||||||
do { \
|
|
||||||
ball = (Vector2){paddle.x + paddle.width * 0.5f, \
|
|
||||||
paddleY - ballRadius - 2.0f}; \
|
|
||||||
ballV = (Vector2){BALL_SPEED_INIT * 0.6f, -BALL_SPEED_INIT}; \
|
|
||||||
ballLaunched = false; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
while (!WindowShouldClose()) {
|
|
||||||
float dt = GetFrameTime();
|
|
||||||
if (dt > 0.05f)
|
|
||||||
dt = 0.05f;
|
|
||||||
|
|
||||||
if (GetScreenWidth() != sw || GetScreenHeight() != sh) {
|
|
||||||
sw = GetScreenWidth();
|
|
||||||
sh = GetScreenHeight();
|
|
||||||
|
|
||||||
paddleW = sw * 0.22f;
|
|
||||||
paddleH = sh * 0.022f;
|
|
||||||
paddleY = sh - sh * 0.10f;
|
|
||||||
ballRadius = sw * 0.022f;
|
|
||||||
brickAreaTop = sh * 0.22f;
|
|
||||||
brickAreaH = sh * 0.32f;
|
|
||||||
|
|
||||||
paddle.width = paddleW;
|
|
||||||
paddle.height = paddleH;
|
|
||||||
paddle.y = paddleY;
|
|
||||||
|
|
||||||
BuildBricks(bricks, (float)sw, brickAreaTop, brickAreaH);
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2 pointer =
|
|
||||||
GetTouchPointCount() > 0 ? GetTouchPosition(0) : GetMousePosition();
|
|
||||||
|
|
||||||
bool tapped = IsMouseButtonPressed(MOUSE_BUTTON_LEFT);
|
|
||||||
|
|
||||||
Rectangle pauseRect = {sw - ui.margin - ui.buttonWidth, ui.margin,
|
|
||||||
ui.buttonWidth, ui.buttonHeight};
|
|
||||||
Rectangle buttonRect = {sw * 0.5f - ui.actionWidth * 0.5f,
|
|
||||||
sh - ui.margin - ui.actionHeight, ui.actionWidth,
|
|
||||||
ui.actionHeight};
|
|
||||||
Rectangle menuRect = {sw * 0.5f - ui.actionWidth * 0.5f,
|
|
||||||
sh - ui.margin - ui.actionHeight * 2.0f - 8.0f,
|
|
||||||
ui.actionWidth, ui.actionHeight};
|
|
||||||
Rectangle launchRect = {ui.margin, sh * 0.44f, sw - ui.margin * 2.0f,
|
|
||||||
sh - sh * 0.44f - ui.margin};
|
|
||||||
|
|
||||||
bool pausePressed = tapped && CheckCollisionPointRec(pointer, pauseRect) &&
|
|
||||||
(state == STATE_PLAYING || state == STATE_PAUSED);
|
|
||||||
bool buttonPressed = tapped && CheckCollisionPointRec(pointer, buttonRect);
|
|
||||||
bool menuPressed = tapped && CheckCollisionPointRec(pointer, menuRect);
|
|
||||||
bool launchPressed = tapped && CheckCollisionPointRec(pointer, launchRect);
|
|
||||||
|
|
||||||
if (state == STATE_TITLE) {
|
|
||||||
|
|
||||||
if (buttonPressed)
|
|
||||||
state = STATE_PLAYING;
|
|
||||||
|
|
||||||
} else if (state == STATE_PAUSED) {
|
|
||||||
|
|
||||||
if (pausePressed)
|
|
||||||
state = STATE_PLAYING;
|
|
||||||
|
|
||||||
} else if (state == STATE_WIN || state == STATE_LOSE) {
|
|
||||||
|
|
||||||
if (buttonPressed) {
|
|
||||||
score = 0;
|
|
||||||
lives = 3;
|
|
||||||
aliveBricks = totalBricks;
|
|
||||||
paddle.x = sw * 0.5f - paddleW * 0.5f;
|
|
||||||
BuildBricks(bricks, (float)sw, brickAreaTop, brickAreaH);
|
|
||||||
RESET_BALL();
|
|
||||||
state = STATE_PLAYING;
|
|
||||||
|
|
||||||
} else if (menuPressed) {
|
|
||||||
score = 0;
|
|
||||||
lives = 3;
|
|
||||||
aliveBricks = totalBricks;
|
|
||||||
paddle.x = sw * 0.5f - paddleW * 0.5f;
|
|
||||||
BuildBricks(bricks, (float)sw, brickAreaTop, brickAreaH);
|
|
||||||
RESET_BALL();
|
|
||||||
state = STATE_TITLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
paddle.x = Clamp(pointer.x - paddle.width * 0.5f, 0.0f,
|
|
||||||
(float)sw - paddle.width);
|
|
||||||
|
|
||||||
if (pausePressed) {
|
|
||||||
state = STATE_PAUSED;
|
|
||||||
|
|
||||||
} else if (launchPressed && !ballLaunched) {
|
|
||||||
ballLaunched = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ballLaunched) {
|
|
||||||
ball.x += ballV.x * dt;
|
|
||||||
ball.y += ballV.y * dt;
|
|
||||||
|
|
||||||
if (ball.x - ballRadius <= 0.0f) {
|
|
||||||
ball.x = ballRadius;
|
|
||||||
ballV.x = fabsf(ballV.x);
|
|
||||||
}
|
|
||||||
if (ball.x + ballRadius >= sw) {
|
|
||||||
ball.x = sw - ballRadius;
|
|
||||||
ballV.x = -fabsf(ballV.x);
|
|
||||||
}
|
|
||||||
if (ball.y - ballRadius <= 0.0f) {
|
|
||||||
ball.y = ballRadius;
|
|
||||||
ballV.y = fabsf(ballV.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ball.y - ballRadius > sh) {
|
|
||||||
lives--;
|
|
||||||
if (lives <= 0)
|
|
||||||
state = STATE_LOSE;
|
|
||||||
else
|
|
||||||
RESET_BALL();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CollideBallRect(&ball, &ballV, ballRadius, paddle, dt)) {
|
|
||||||
float hitPos = (ball.x - paddle.x) / paddle.width;
|
|
||||||
float angle = (hitPos - 0.5f) * 120.0f * DEG2RAD;
|
|
||||||
float speed = Vector2Length(ballV);
|
|
||||||
speed = Clamp(speed + 10.0f, 0.0f, BALL_SPEED_MAX);
|
|
||||||
ballV.x = sinf(angle) * speed;
|
|
||||||
ballV.y = -fabsf(cosf(angle) * speed);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int r = 0; r < BRICK_ROWS; r++) {
|
|
||||||
for (int c = 0; c < BRICK_COLS; c++) {
|
|
||||||
Brick *b = &bricks[r][c];
|
|
||||||
if (!b->alive)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (CollideBallRect(&ball, &ballV, ballRadius, b->rect, dt)) {
|
|
||||||
b->alive = false;
|
|
||||||
aliveBricks--;
|
|
||||||
score += b->points;
|
|
||||||
if (aliveBricks <= 0)
|
|
||||||
state = STATE_WIN;
|
|
||||||
goto done_bricks;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
done_bricks:;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
ball.x = paddle.x + paddle.width * 0.5f;
|
|
||||||
ball.y = paddleY - ballRadius - 2.0f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BeginDrawing();
|
|
||||||
ClearBackground(ui.background);
|
|
||||||
|
|
||||||
if (state == STATE_TITLE) {
|
|
||||||
if (logo.id != 0) {
|
|
||||||
float targetSize = sh * 0.12f;
|
|
||||||
float scale = targetSize / (float)logo.width;
|
|
||||||
DrawTextureEx(logo, (Vector2){sw * 0.5f - targetSize * 0.5f, 8.0f},
|
|
||||||
0.0f, scale, WHITE);
|
|
||||||
}
|
|
||||||
|
|
||||||
int ts = sw / 10;
|
|
||||||
int ss = sw / 22;
|
|
||||||
DrawText("BREAKOUT", sw / 2 - MeasureText("BREAKOUT", ts) / 2,
|
|
||||||
(int)(sh * 0.18f), ts, (Color){60, 180, 255, 255});
|
|
||||||
DrawText("tap the button to start",
|
|
||||||
sw / 2 - MeasureText("tap the button to start", ss) / 2,
|
|
||||||
(int)(sh * 0.18f) + ts + 8, ss, (Color){160, 170, 190, 255});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state != STATE_TITLE) {
|
|
||||||
for (int r = 0; r < BRICK_ROWS; r++) {
|
|
||||||
for (int c = 0; c < BRICK_COLS; c++) {
|
|
||||||
Brick *b = &bricks[r][c];
|
|
||||||
if (!b->alive)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
DrawRectangleRounded(b->rect, 0.25f, 6, b->color);
|
|
||||||
DrawLineEx((Vector2){b->rect.x + 4, b->rect.y + 2},
|
|
||||||
(Vector2){b->rect.x + b->rect.width - 4, b->rect.y + 2},
|
|
||||||
1.5f, (Color){255, 255, 255, 60});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DrawRectangleRounded(paddle, 0.5f, 8, (Color){60, 180, 255, 255});
|
|
||||||
DrawCircleV(ball, ballRadius, WHITE);
|
|
||||||
DrawCircleLines((int)ball.x, (int)ball.y, ballRadius + 2,
|
|
||||||
(Color){255, 255, 255, 60});
|
|
||||||
|
|
||||||
int hs = sw / 24;
|
|
||||||
DrawText(TextFormat("Score: %d", score), 14, 14, hs,
|
|
||||||
(Color){200, 210, 225, 255});
|
|
||||||
DrawText(TextFormat("Lives: %d", lives), 14, 14 + hs + 8, hs,
|
|
||||||
(Color){255, 80, 80, 255});
|
|
||||||
|
|
||||||
if (!ballLaunched && state == STATE_PLAYING) {
|
|
||||||
const char *hint = "tap anywhere to launch";
|
|
||||||
int hintSize = sw / 26;
|
|
||||||
DrawText(hint, sw / 2 - MeasureText(hint, hintSize) / 2,
|
|
||||||
(int)(sh * 0.72f), hintSize, ui.muted);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state == STATE_PAUSED) {
|
|
||||||
DrawRectangle(0, 0, sw, sh, (Color){0, 0, 0, 150});
|
|
||||||
|
|
||||||
int ts = sw / 10;
|
|
||||||
int ss = sw / 22;
|
|
||||||
DrawText("PAUSED", sw / 2 - MeasureText("PAUSED", ts) / 2, sh / 2 - ts,
|
|
||||||
ts, RAYWHITE);
|
|
||||||
DrawText("tap resume to continue",
|
|
||||||
sw / 2 - MeasureText("tap resume to continue", ss) / 2,
|
|
||||||
sh / 2 + ts, ss, (Color){160, 170, 190, 180});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state == STATE_WIN || state == STATE_LOSE) {
|
|
||||||
DrawRectangle(0, 0, sw, sh, (Color){0, 0, 0, 160});
|
|
||||||
|
|
||||||
const char *title = state == STATE_WIN ? "YOU WIN!" : "GAME OVER";
|
|
||||||
Color tcol = state == STATE_WIN ? (Color){80, 220, 100, 255}
|
|
||||||
: (Color){255, 80, 80, 255};
|
|
||||||
int ts = sw / 9;
|
|
||||||
int ss = sw / 22;
|
|
||||||
|
|
||||||
DrawText(title, sw / 2 - MeasureText(title, ts) / 2, sh / 2 - ts, ts,
|
|
||||||
tcol);
|
|
||||||
DrawText(TextFormat("Score: %d", score),
|
|
||||||
sw / 2 - MeasureText(TextFormat("Score: %d", score), ss) / 2,
|
|
||||||
sh / 2 + ts / 4, ss, (Color){200, 210, 225, 255});
|
|
||||||
|
|
||||||
const char *msg = state == STATE_WIN ? "tap retry to play again"
|
|
||||||
: "tap retry to try again";
|
|
||||||
DrawText(msg, sw / 2 - MeasureText(msg, ss) / 2, sh / 2 + ts, ss,
|
|
||||||
(Color){160, 170, 190, 200});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state == STATE_PLAYING || state == STATE_PAUSED) {
|
|
||||||
const char *pauseText = state == STATE_PAUSED ? "RESUME" : "PAUSE";
|
|
||||||
DrawRectangleRounded(pauseRect, ui.roundness, 8, ui.panel);
|
|
||||||
DrawText(pauseText,
|
|
||||||
(int)(pauseRect.x + pauseRect.width * 0.5f -
|
|
||||||
(float)MeasureText(pauseText, 16) * 0.5f),
|
|
||||||
(int)(pauseRect.y + 8), 16, ui.text);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool drawActionButton =
|
|
||||||
(state == STATE_TITLE) || (state == STATE_WIN || state == STATE_LOSE);
|
|
||||||
if (drawActionButton) {
|
|
||||||
const char *buttonText =
|
|
||||||
(state == STATE_WIN || state == STATE_LOSE) ? "RETRY" : "START";
|
|
||||||
Rectangle actionButton = {sw * 0.5f - ui.actionWidth * 0.5f,
|
|
||||||
sh - ui.margin - ui.actionHeight,
|
|
||||||
ui.actionWidth, ui.actionHeight};
|
|
||||||
DrawRectangleRounded(actionButton, ui.roundness, 8, ui.panel);
|
|
||||||
DrawText(buttonText,
|
|
||||||
(int)(actionButton.x + actionButton.width * 0.5f -
|
|
||||||
(float)MeasureText(buttonText, 18) * 0.5f),
|
|
||||||
(int)(actionButton.y + 8), 18, ui.text);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state == STATE_WIN || state == STATE_LOSE) {
|
|
||||||
const char *menuText = "MAIN MENU";
|
|
||||||
DrawRectangleRounded(menuRect, ui.roundness, 8, ui.panel);
|
|
||||||
DrawText(menuText,
|
|
||||||
(int)(menuRect.x + menuRect.width * 0.5f -
|
|
||||||
(float)MeasureText(menuText, 18) * 0.5f),
|
|
||||||
(int)(menuRect.y + 8), 18, ui.text);
|
|
||||||
}
|
|
||||||
|
|
||||||
EndDrawing();
|
|
||||||
}
|
|
||||||
|
|
||||||
UnloadTexture(logo);
|
|
||||||
CloseWindow();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue
Block a user