slifer 0.2.2 → 0.2.4

Sign up to get free protection for your applications and to get access to all the features.
package/.npmignore ADDED
@@ -0,0 +1,137 @@
1
+ # Logs
2
+ logs
3
+ *.log
4
+ npm-debug.log*
5
+ yarn-debug.log*
6
+ yarn-error.log*
7
+ lerna-debug.log*
8
+ .pnpm-debug.log*
9
+ .vs
10
+ Resources
11
+ .idea
12
+
13
+ # Diagnostic reports (https://nodejs.org/api/report.html)
14
+ report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
15
+
16
+ # Runtime data
17
+ pids
18
+ *.pid
19
+ *.seed
20
+ *.pid.lock
21
+
22
+ # Directory for instrumented libs generated by jscoverage/JSCover
23
+ lib-cov
24
+
25
+ # Coverage directory used by tools like istanbul
26
+ coverage
27
+ *.lcov
28
+
29
+ # nyc test coverage
30
+ .nyc_output
31
+
32
+ # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
33
+ .grunt
34
+
35
+ # Bower dependency directory (https://bower.io/)
36
+ bower_components
37
+
38
+ # node-waf configuration
39
+ .lock-wscript
40
+
41
+ # Compiled binary addons (https://nodejs.org/api/addons.html)
42
+ build/Release
43
+
44
+ # Dependency directories
45
+ node_modules/
46
+ jspm_packages/
47
+
48
+ # Snowpack dependency directory (https://snowpack.dev/)
49
+ web_modules/
50
+
51
+ # TypeScript cache
52
+ *.tsbuildinfo
53
+
54
+ # Optional npm cache directory
55
+ .npm
56
+
57
+ # Optional eslint cache
58
+ .eslintcache
59
+
60
+ # Optional stylelint cache
61
+ .stylelintcache
62
+
63
+ # Microbundle cache
64
+ .rpt2_cache/
65
+ .rts2_cache_cjs/
66
+ .rts2_cache_es/
67
+ .rts2_cache_umd/
68
+
69
+ # Optional REPL history
70
+ .node_repl_history
71
+
72
+ # Output of 'npm pack'
73
+ *.tgz
74
+
75
+ # Yarn Integrity file
76
+ .yarn-integrity
77
+
78
+ # dotenv environment variable files
79
+ .env
80
+ .env.development.local
81
+ .env.test.local
82
+ .env.production.local
83
+ .env.local
84
+
85
+ # parcel-bundler cache (https://parceljs.org/)
86
+ .cache
87
+ .parcel-cache
88
+
89
+ # Next.js build output
90
+ .next
91
+ out
92
+
93
+ # Nuxt.js build / generate output
94
+ .nuxt
95
+ dist
96
+
97
+ # Gatsby files
98
+ .cache/
99
+ # Comment in the public line in if your project uses Gatsby and not Next.js
100
+ # https://nextjs.org/blog/next-9-1#public-directory-support
101
+ # public
102
+
103
+ # vuepress build output
104
+ .vuepress/dist
105
+
106
+ # vuepress v2.x temp and cache directory
107
+ .temp
108
+ .cache
109
+
110
+ # Docusaurus cache and generated files
111
+ .docusaurus
112
+
113
+ # Serverless directories
114
+ .serverless/
115
+
116
+ # FuseBox cache
117
+ .fusebox/
118
+
119
+ # DynamoDB Local files
120
+ .dynamodb/
121
+
122
+ # TernJS port file
123
+ .tern-port
124
+
125
+ # Stores VSCode versions used for testing VSCode extensions
126
+ .vscode-test
127
+
128
+ # yarn v2
129
+ .yarn/cache
130
+ .yarn/unplugged
131
+ .yarn/build-state.yml
132
+ .yarn/install-state.gz
133
+ .pnp.*
134
+ test.ts
135
+ char.png
136
+
137
+ .wakatime-project
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Slifer : Native Typescript Game Framework
2
2
 
3
3
  <p align="center">
4
- <img width="80%" src="./logo-alpha.png">
4
+ <img width="80%" src="https://ucarecdn.com/288f053f-61e0-42e6-804a-8c1d48a41aac/-/preview/1000x562/">
5
5
  </p>
6
6
 
7
7
  > [!CAUTION]
@@ -12,12 +12,14 @@
12
12
  > window customization. As such, I recommend waiting for a beta release of
13
13
  > Slifer before using it for a long term project.
14
14
 
15
+ For up to date docs, please head over to the [Slifer Webpage](https://slifer.hazyvt.com).
16
+
17
+ ## Introduction
18
+
15
19
  Slifer is a game framework made to allow users to code games in typescript. The
16
20
  framework uses bun and SDL2 under the hood to allow your game to render and
17
21
  build natively to desktop.
18
22
 
19
- If you'd like to learn more about Slifer, feel free to head to [Slifers Webpage](https://slifer.hazyvt.com).
20
-
21
23
  ## Contents
22
24
 
23
25
  - [Goals](#goals)
@@ -38,19 +40,19 @@ If you'd like to learn more about Slifer, feel free to head to [Slifers Webpage]
38
40
  - Create a native desktop window with custom title and size.
39
41
  - Handle both keyboard and mouse inputs
40
42
  - Load and draw images onto the window
43
+ - Play Audio
41
44
 
42
45
  ## Future Features
43
46
 
44
- - Audio Implementation
45
47
  - Animation library
46
48
  - Save file library
47
49
 
48
50
  ## Example
49
51
 
50
52
  ```ts
51
- import Slifer from "slifer";
53
+ import Slifer, { Vector2 } from "slifer";
52
54
 
53
- Slifer.createWindow("Example Window", 640, 480);
55
+ Slifer.createWindow("Example Window", new Vector2(640, 480));
54
56
 
55
57
  const bg = Slifer.Graphics.makeColor(36, 36, 36, 255);
56
58
 
package/bun.lockb ADDED
Binary file
package/index.ts CHANGED
@@ -1,4 +1,10 @@
1
1
  import { SliferClass } from "./src/slifer";
2
2
 
3
+ export type { ImageType as Image } from "./src/modules/graphics";
4
+ export { Vector2 } from "./src/engine/vector";
5
+ export { Rectangle } from "./src/engine/rectangle";
6
+ export { Timer } from "./src/engine/time";
7
+ export { AudioSource } from "./src/modules/audio";
8
+
3
9
  const Slifer = new SliferClass();
4
- export default Slifer;
10
+ export default Slifer;
Binary file
package/package.json CHANGED
@@ -1,11 +1,10 @@
1
1
  {
2
2
  "name": "slifer",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "A game framework made for bun and typescript",
5
5
  "module": "index.ts",
6
6
  "devDependencies": {
7
- "@types/bun": "latest",
8
- "typedoc": "^0.26.7"
7
+ "@types/bun": "latest"
9
8
  },
10
9
  "peerDependencies": {
11
10
  "typescript": "^5.0.0"
@@ -1,8 +1,8 @@
1
1
  import { ptr } from "bun:ffi";
2
- import Vector2 from "./vector";
2
+ import { Vector2 } from "./vector";
3
3
 
4
- class Rectangle {
5
- private readonly pointer;
4
+ export class Rectangle {
5
+ public readonly pointer;
6
6
  public position: Vector2;
7
7
  public size: Vector2;
8
8
 
@@ -20,6 +20,18 @@ class Rectangle {
20
20
  static empty() {
21
21
  return new Rectangle(new Vector2(0, 0), new Vector2(0, 0));
22
22
  }
23
+
24
+ public isColliding(rectangle: Rectangle) : boolean {
25
+ if (
26
+ this.position.x < rectangle.position.x + rectangle.size.x &&
27
+ this.position.x + this.size.x > rectangle.position.x &&
28
+ this.position.y < rectangle.position.y + rectangle.size.y &&
29
+ this.position.y + this.size.y > rectangle.position.y
30
+ ) {
31
+ return true;
32
+ }
33
+
34
+ return false;
35
+ }
23
36
  }
24
37
 
25
- export default Rectangle;
@@ -25,7 +25,7 @@ class Renderer {
25
25
  const _ren = libsdl.symbols.SDL_CreateRenderer(
26
26
  Window.pointer,
27
27
  -1,
28
- vsyncHint
28
+ 0
29
29
  );
30
30
 
31
31
  if (_ren == null) throw `Renderer Creation Failed`;
@@ -1,34 +1,79 @@
1
1
  import { libsdl } from "../ffi";
2
2
 
3
- class Time {
4
- static #instance: Time;
3
+ export class Timer {
5
4
 
6
- private lastframe: number = 0;
7
- private firstFrame: number = 0;
5
+ private mStartTicks;
6
+ private mPausedTicks;
7
+ private mPaused;
8
+ private mStarted;
9
+
10
+
11
+ constructor() {
12
+ this.mStartTicks = 0;
13
+ this.mPausedTicks = 0;
14
+ this.mPaused = false;
15
+ this.mStarted = false;
16
+ }
17
+
18
+ public start() {
19
+ this.mStarted = true;
8
20
 
9
- private constructor() {}
21
+ this.mPaused = false;
10
22
 
11
- public static get instance() {
12
- if (!Time.#instance) {
13
- Time.#instance = new Time();
14
- }
23
+ this.mStartTicks = libsdl.symbols.SDL_GetTicks();
24
+ this.mPausedTicks = 0;
25
+ }
15
26
 
16
- return Time.#instance;
17
- }
27
+ public stop() {
28
+ this.mStarted = false;
29
+ this.mPaused = true;
18
30
 
19
- public init() {
20
- this.firstFrame = Number(libsdl.symbols.SDL_GetPerformanceCounter());
21
- }
31
+ this.mStartTicks = 0;
32
+ this.mPausedTicks = 0;
33
+ }
22
34
 
23
- public calcDelta(): number {
24
- this.lastframe = this.firstFrame;
25
- this.firstFrame = Number(libsdl.symbols.SDL_GetPerformanceCounter());
26
- const deltaTime =
27
- ((this.firstFrame - this.lastframe) * 1000) /
28
- Number(libsdl.symbols.SDL_GetPerformanceFrequency());
35
+ public pause() {
36
+ if (this.mStarted && !this.mPaused) {
37
+ this.mPaused = true;
29
38
 
30
- return deltaTime;
31
- }
39
+ this.mPausedTicks = libsdl.symbols.SDL_GetTicks() - this.mStartTicks;
40
+ this.mStartTicks = 0;
41
+ }
42
+ }
43
+
44
+ public unpause() {
45
+ if (this.mStarted && this.mPaused) {
46
+ this.mPaused = false;
47
+
48
+ this.mStartTicks = libsdl.symbols.SDL_GetTicks() - this.mPausedTicks;
49
+ this.mPausedTicks = 0;
50
+ }
51
+ }
52
+
53
+ public getTicks() {
54
+ let time = 0;
55
+
56
+ if (this.mStarted) {
57
+ if (this.mPaused) {
58
+ time = this.mPausedTicks;
59
+ } else {
60
+ time = libsdl.symbols.SDL_GetTicks() - this.mStartTicks;
61
+ }
62
+ }
63
+
64
+ return time;
65
+ }
66
+
67
+ public isStarted() {
68
+ return this.mStarted;
69
+ }
70
+
71
+ public isPaused() {
72
+ return (this.mPaused && this.mStarted);
73
+ }
74
+
75
+
76
+
77
+
32
78
  }
33
79
 
34
- export default Time;
@@ -1,4 +1,4 @@
1
- class Vector2 {
1
+ export class Vector2 {
2
2
  public x;
3
3
  public y;
4
4
 
@@ -45,5 +45,3 @@ class Vector2 {
45
45
  return new Vector2(vec1.x + vec2.x, vec1.y + vec2.y);
46
46
  }
47
47
  }
48
-
49
- export default Vector2;
@@ -1,5 +1,5 @@
1
1
  import { type Pointer } from "bun:ffi";
2
- import Vector2 from "./vector";
2
+ import { Vector2 } from "./vector";
3
3
  import { libsdl } from "../ffi";
4
4
 
5
5
  class Window {
package/src/ffi.ts CHANGED
@@ -12,6 +12,8 @@ if (process.platform == "win32") {
12
12
  libImageImport = await import("../libs/libSDL2_image.dll");
13
13
  //@ts-expect-error
14
14
  libTTFImport = await import("../libs/libSDL2_ttf.dll");
15
+ //@ts-expect-error
16
+ libMixerImport = await import("../libs/libSDL2_mixer.dll");
15
17
  } else if (process.platform == "darwin") {
16
18
  //@ts-expect-error
17
19
  libSDLImport = await import("../libs/libSDL2.dylib");
@@ -30,7 +32,6 @@ if (process.platform == "win32") {
30
32
  libTTFImport = await import("../libs/libSDL2_ttf.so");
31
33
  //@ts-expect-error
32
34
  libMixerImport = await import("../libs/libSDL2_mixer.so");
33
-
34
35
  }
35
36
 
36
37
  /** @internal */
@@ -206,10 +207,20 @@ export const libsdl = dlopen(libSDLImport.default, {
206
207
  args: ["pointer", "cstring"],
207
208
  returns: "void",
208
209
  },
209
- SDL_LoadWAV_RW: {
210
- args: ["cstring", "pointer", "pointer", "pointer"],
210
+ SDL_GetTicks: {
211
+ returns: "uint32_t",
212
+ },
213
+ SDL_Delay: {
214
+ args: ["uint32_t"],
215
+ },
216
+ SDL_GetKeyboardState: {
217
+ args: ["pointer"],
211
218
  returns: "pointer",
212
219
  },
220
+ SDL_GetScancodeFromName: {
221
+ args: ["cstring"],
222
+ returns: "int",
223
+ },
213
224
  });
214
225
 
215
226
  /** @internal */
@@ -17,7 +17,7 @@ class Audio {
17
17
  }
18
18
  }
19
19
 
20
- class AudioSource {
20
+ export class AudioSource {
21
21
  public readonly pointer;
22
22
 
23
23
  constructor(path: string) {
@@ -1,8 +1,8 @@
1
- import { libimage, libsdl, libttf } from "../ffi";
1
+ import { libimage, libsdl } from "../ffi";
2
2
  import { type Pointer, ptr } from "bun:ffi";
3
- import Rectangle from "../engine/rectangle";
3
+ import { Rectangle } from "../engine/rectangle";
4
4
  import Color from "../color";
5
- import Vector2 from "../engine/vector";
5
+ import { Vector2 } from "../engine/vector";
6
6
  import Renderer from "../engine/renderer";
7
7
 
8
8
  class Graphics {
@@ -65,6 +65,7 @@ class Graphics {
65
65
  */
66
66
  public loadImage(path: string): Image {
67
67
  const _path = Buffer.from(path + "\x00");
68
+ //@ts-expect-error
68
69
  const surface = libimage.symbols.IMG_Load(_path);
69
70
  if (surface == null) throw `Image failed to load`;
70
71
  const texture = libsdl.symbols.SDL_CreateTextureFromSurface(
@@ -109,7 +110,8 @@ class Graphics {
109
110
  image: Image,
110
111
  position: Vector2,
111
112
  rotation?: number,
112
- scale?: Vector2
113
+ scale?: Vector2,
114
+ flipH?: boolean
113
115
  ) {
114
116
  // Define destination rect
115
117
  const dstRect = new Uint32Array(4);
@@ -126,14 +128,26 @@ class Graphics {
126
128
  ptr(dstRect),
127
129
  rotation ? rotation : 0,
128
130
  null,
129
- null
131
+ flipH ? Number(flipH) : 0
130
132
  );
131
133
  }
134
+
135
+ public drawRect(rectangle: Rectangle, color: Color) {
136
+ libsdl.symbols.SDL_SetRenderDrawColor(
137
+ Renderer.pointer,
138
+ color.r,
139
+ color.g,
140
+ color.b,
141
+ color.a
142
+ );
143
+ libsdl.symbols.SDL_RenderFillRect(Renderer.pointer, rectangle.pointer);
144
+ }
132
145
  }
133
146
 
134
147
  class Image {
135
148
  public readonly pointer: Pointer;
136
149
  public readonly size: Vector2;
150
+ public flipH: boolean = false;
137
151
 
138
152
  constructor(texture: Pointer) {
139
153
  this.pointer = texture;
@@ -153,5 +167,7 @@ class Image {
153
167
  }
154
168
  }
155
169
 
170
+ export type ImageType = Image;
171
+
156
172
  /** @internal */
157
173
  export default Graphics;
@@ -1,12 +1,12 @@
1
1
  import { libsdl } from "../ffi";
2
+ import { toArrayBuffer } from "bun:ffi";
2
3
 
3
4
  /** @internal */
4
5
  class Keyboard {
5
6
  static #instance: Keyboard;
6
7
 
7
- static downKeyMap = new Map<string, boolean>();
8
- static pressedKeyMap = new Map<string, boolean>();
9
- static releasedKeyMap = new Map<string, boolean>();
8
+ static keyState: DataView;
9
+ static pressMap = new Map<string, number>();
10
10
 
11
11
  private constructor() {}
12
12
 
@@ -27,63 +27,49 @@ class Keyboard {
27
27
  return keyName;
28
28
  }
29
29
 
30
- static setKeyDown(key: number): void {
31
- const keyName = Keyboard.convertScancodeToKey(key);
32
- this.downKeyMap.set(keyName.toLowerCase(), true);
33
- this.releasedKeyMap.set(keyName.toLowerCase(), false);
34
- }
35
-
36
- static setKeyUp(key: number) {
37
- const keyName = Keyboard.convertScancodeToKey(key);
38
- this.downKeyMap.set(keyName.toLowerCase(), false);
39
- this.pressedKeyMap.set(keyName.toLowerCase(), false);
40
- }
41
-
42
- /**
43
- *
44
- * @param key string of key
45
- * @returns if the key is being held down
46
- */
47
- isDown(key: keys) {
48
- const _state = Keyboard.downKeyMap.get(key);
49
- if (_state == undefined) return false;
50
-
51
- return _state;
30
+ static getStates() {
31
+ const state = libsdl.symbols.SDL_GetKeyboardState(null);
32
+ if (state == null) return;
33
+ const myArr = new DataView(toArrayBuffer(state, 0, 512));
34
+
35
+ for (let i = 0; i < 512; ++i) {
36
+ if (myArr.getUint8(i) == 1) {
37
+ const keyName = this.convertScancodeToKey(i).toLowerCase();
38
+ const kmGet = this.pressMap.get(keyName);
39
+ if (kmGet == undefined || kmGet == 0) {
40
+ this.pressMap.set(keyName, 1);
41
+ } else if (kmGet == 1) {
42
+ this.pressMap.set(keyName, 2);
43
+ }
44
+ } else if (myArr.getUint8(i) == 0) {
45
+ const keyName = this.convertScancodeToKey(i).toLowerCase();
46
+ this.pressMap.set(keyName, 0);
47
+ }
48
+ }
52
49
  }
53
50
 
54
- /**
55
- *
56
- * @param key string of key
57
- * @returns if key is pressed. Returns only once
58
- */
59
- isPressed(key: keys) {
60
- const _pressedState = Keyboard.pressedKeyMap.get(key);
61
- const _downState = Keyboard.downKeyMap.get(key);
62
-
63
- if (_downState == true) {
64
- if (_pressedState == false || _pressedState == undefined) {
65
- Keyboard.pressedKeyMap.set(key, true);
66
- return true;
67
- }
51
+ public isPressed(key: keys) {
52
+ /*
53
+ const scancode = libsdl.symbols.SDL_GetScancodeFromName(
54
+ Buffer.from(key + "\x00")
55
+ );
56
+ const thisval = Keyboard.keyState.getUint8(scancode);
57
+ */
58
+
59
+ const kmGet = Keyboard.pressMap.get(key);
60
+ if (kmGet == 1) {
61
+ return true;
68
62
  }
69
63
 
64
+
70
65
  return false;
71
66
  }
72
67
 
73
- /**
74
- *
75
- * @param key string of key
76
- * @returns if key is released. Returns only once
77
- */
78
- isReleased(key: keys) {
79
- const _releasedState = Keyboard.releasedKeyMap.get(key);
80
- const _downState = Keyboard.downKeyMap.get(key);
81
-
82
- if (_downState == false) {
83
- if (_releasedState == false || undefined) {
84
- Keyboard.releasedKeyMap.set(key, true);
85
- return true;
86
- }
68
+
69
+ public isDown(key: keys) {
70
+ const kmGet = Keyboard.pressMap.get(key);
71
+ if (kmGet == 1 || kmGet == 2) {
72
+ return true;
87
73
  }
88
74
 
89
75
  return false;
@@ -1,6 +1,6 @@
1
1
  import { libsdl } from "../ffi";
2
2
  import { ptr } from "bun:ffi";
3
- import Vector2 from "../engine/vector";
3
+ import {Vector2} from "../engine/vector";
4
4
 
5
5
  /** @internal */
6
6
  class Mouse {
package/src/slifer.ts CHANGED
@@ -5,8 +5,8 @@ import Mouse from "./modules/mouse";
5
5
  import Audio from "./modules/audio";
6
6
  import Window from "./engine/window";
7
7
  import Renderer from "./engine/renderer";
8
- import Vector2 from "./engine/vector";
9
- import Time from "./engine/time";
8
+ import { Vector2 } from "./engine/vector";
9
+ import { Timer } from "./engine/time";
10
10
  import { ptr } from "bun:ffi";
11
11
  import { initLibraries } from "./engine";
12
12
  import { version } from "../package.json";
@@ -23,8 +23,13 @@ export class SliferClass {
23
23
  public dt: number = 0;
24
24
  public isRunning: boolean = true;
25
25
 
26
+ private fps = 60;
27
+ private ticksPerFrame = 1000 / this.fps;
28
+ private capTimer: Timer;
29
+
26
30
  constructor() {
27
31
  initLibraries();
32
+ this.capTimer = new Timer();
28
33
  }
29
34
 
30
35
  /**
@@ -40,9 +45,6 @@ export class SliferClass {
40
45
  // Create the renderer
41
46
  Renderer.createRenderer();
42
47
 
43
- // Start delta time calculations
44
- Time.instance.init();
45
-
46
48
  // Return the window object
47
49
  return window;
48
50
  }
@@ -51,11 +53,14 @@ export class SliferClass {
51
53
  * @returns if the window should close
52
54
  */
53
55
  shouldClose(): boolean {
56
+ this.capTimer.start();
57
+
54
58
  // Clear the renderer
55
59
  Renderer.clear();
56
60
 
61
+
57
62
  // Calculate delta time
58
- this.dt = Time.instance.calcDelta();
63
+ // this.dt = Time.instance.calcDelta();
59
64
 
60
65
  // Poll Events
61
66
  const eventArray = new Uint16Array(32);
@@ -67,16 +72,6 @@ export class SliferClass {
67
72
  case 256:
68
73
  this.isRunning = false;
69
74
  break;
70
- // Keydown event
71
- case 768:
72
- var scancode = eventArray[8];
73
- Keyboard.setKeyDown(scancode);
74
- break;
75
- // Keyup event
76
- case 769:
77
- var scancode = eventArray[8];
78
- Keyboard.setKeyUp(scancode);
79
- break;
80
75
  // Mouse down event
81
76
  case 1025:
82
77
  const _dbtn = eventArray[8] - 256;
@@ -90,6 +85,14 @@ export class SliferClass {
90
85
  }
91
86
  }
92
87
 
88
+ Keyboard.getStates();
89
+
90
+ const frameTicks = this.capTimer.getTicks();
91
+ if (frameTicks < this.ticksPerFrame) {
92
+ libsdl.symbols.SDL_Delay(this.ticksPerFrame - frameTicks);
93
+ }
94
+
95
+
93
96
  return !this.isRunning;
94
97
  }
95
98
 
@@ -105,4 +108,9 @@ export class SliferClass {
105
108
  getVersion() {
106
109
  return version;
107
110
  }
111
+
112
+ setFps(fps: number) {
113
+ this.fps = fps;
114
+ this.ticksPerFrame = 1000 / fps;
115
+ }
108
116
  }
package/Logo.png DELETED
Binary file
package/Sir-BC_stop.png DELETED
Binary file
package/logo-alpha.png DELETED
Binary file
package/sample.wav DELETED
Binary file