Skip to content

Commit d550b20

Browse files
rd-160052 (160052)
1 parent f2d9b5b commit d550b20

35 files changed

+998
-427
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ install:
1212
CYTHONIZE=1 pip install .
1313

1414
install-from-source: dist
15-
pip install dist/minecraft-python-132328.tar.gz
15+
pip install dist/minecraft-python-160052.tar.gz
1616

1717
clean:
1818
$(RM) -r build dist src/*.egg-info

README.md

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,25 @@
44

55
_**Minecraft: Python Edition**_ is a project that strives to recreate each and every old Minecraft version in Python using the **Pyglet** multimedia library and **Cython** for performance.
66

7-
This project is currently recreating the **Preclassic** versions of Minecraft. The latest version is **Preclassic rd-132328** as released on _**May 13, 2009**_.
7+
This project is currently recreating the **Preclassic** versions of Minecraft. The latest version is **Preclassic rd-160052** as released on _**May 15, 2009**_.
88

9-
Learn more about this version [here](https://minecraft.fandom.com/wiki/Java_Edition_pre-Classic_rd-132328).
9+
Learn more about this version [here](https://minecraft.fandom.com/wiki/Java_Edition_pre-Classic_rd-160052).
1010

1111
### General Usage
1212

1313
*Pyglet* and *Cython* are required dependencies and can easily be installed with *pip*. Use the versions specified in `requirements.txt`.
1414

15-
To easily install this version of *Minecraft: Python Edition*, just run `python -m pip install minecraft-python==132328`.
15+
To easily install this version of *Minecraft: Python Edition*, just run `python -m pip install minecraft-python==160052`.
1616

1717
Alternatively, for a manual Cython build, run `python setup.py build_ext --inplace`.
1818

1919
Run `python -m mc.net.minecraft.Minecraft` to launch the game. *Minecraft: Python Edition* should be compatible with any modern platform that supports OpenGL and Cython.
2020

2121
### Gameplay
2222

23-
Very basic block picking and placing are featured in this version. You can only place stone tiles, except at exact ground level where it is only grass.
23+
Basic terrain, early block picking and placing, and human mobs are featured in this version. There are four different blocks you can place.
2424

25-
Human mobs are featured in this version, but they are all spawned at game start as opposed to on key press.
26-
27-
Press *Esc* to exit the game.
25+
Press *Esc* to exit the game. Press *Return* to save, *R* to reset your position, *G* to spawn a mob, and numbers *1-4* to switch blocks.
2826

2927
### Additional Notes
3028

mc/Resources.py

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

mc/net/minecraft/Entity.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,12 @@ class Entity:
1616
xRotO = 0.0
1717
onGround = False
1818

19+
removed = False
1920
heightOffset = 0.0
2021

22+
bbWidth = 0.6
23+
bbHeight = 1.8
24+
2125
def __init__(self, level):
2226
self.level = level
2327
self.resetPos()
@@ -28,12 +32,19 @@ def resetPos(self):
2832
z = random.random() * self.level.height
2933
self.setPos(x, y, z)
3034

35+
def remove(self):
36+
self.removed = True
37+
38+
def setSize(self, w, h):
39+
self.bbWidth = w
40+
self.bbHeight = h
41+
3142
def setPos(self, x, y, z):
3243
self.x = x
3344
self.y = y
3445
self.z = z
35-
w = 0.3
36-
h = 0.9
46+
w = self.bbWidth / 2.0
47+
h = self.bbHeight / 2.0
3748
self.bb = AABB(x - w, y - h, z - w, x + w, y + h, z + w)
3849

3950
def turn(self, xo, yo):
@@ -83,6 +94,7 @@ def move(self, xa, ya, za):
8394
self.yd = 0.0
8495
if zaOrg != za:
8596
self.zd = 0.0
97+
8698
self.x = (self.bb.x0 + self.bb.x1) / 2.0
8799
self.y = self.bb.y0 + self.heightOffset
88100
self.z = (self.bb.z0 + self.bb.z1) / 2.0
@@ -101,3 +113,6 @@ def moveRelative(self, xa, za, speed):
101113

102114
self.xd += xa * cos - za * sin
103115
self.zd += za * cos + xa * sin
116+
117+
def isLit(self):
118+
return self.level.isLit(self.x, self.y, self.z)

mc/net/minecraft/Minecraft.py

Lines changed: 144 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,34 +3,58 @@
33

44
from mc.net.minecraft.Timer import Timer
55
from mc.net.minecraft.Player import Player
6+
from mc.net.minecraft.Textures import Textures
67
from mc.net.minecraft.HitResult import HitResult
78
from mc.net.minecraft.character.Vec3 import Vec3
8-
from mc.net.minecraft.character.Cube import Cube
99
from mc.net.minecraft.character.Zombie import Zombie
10+
from mc.net.minecraft.level.tile.Tile import Tile
11+
from mc.net.minecraft.level.tile.Tiles import tiles
12+
from mc.net.minecraft.level.Tesselator import tesselator
13+
from mc.net.minecraft.level.Frustum import Frustum
1014
from mc.net.minecraft.level.Chunk import Chunk
1115
from mc.net.minecraft.level.Level import Level
1216
from mc.net.minecraft.level.LevelRenderer import LevelRenderer
17+
from mc.net.minecraft.particle.ParticleEngine import ParticleEngine
1318
from mc.CompatibilityShims import BufferUtils, gluPerspective, getMillis
1419
from pyglet import window, canvas, clock, gl, compat_platform
1520

1621
import math
1722

1823
class Minecraft(window.Window):
1924
FULLSCREEN_MODE = False
20-
col = 920330
21-
fogColor = ((col >> 16 & 0xFF) / 255.0, (col >> 8 & 0xFF) / 255.0, (col & 0xFF) / 255.0, (col & 0xFF) / 255.0, 1.0)
22-
timer = Timer(60.0)
25+
timer = Timer(20.0)
26+
running = True
27+
paintTexture = 1
28+
2329
zombies = set()
30+
2431
hitResult = None
25-
running = True
32+
33+
lb = BufferUtils.createFloatBuffer(16)
2634

2735
def __init__(self, *args, **kwargs):
2836
super().__init__(*args, **kwargs)
2937

38+
col0 = 16710650
39+
col1 = 920330
40+
41+
self.fogColor0 = ((col0 >> 16 & 0xFF) / 255.0, (col0 >> 8 & 0xFF) / 255.0, (col0 & 0xFF) / 255.0, (col0 & 0xFF) / 255.0, 1.0)
42+
self.fogColor1 = ((col1 >> 16 & 0xFF) / 255.0, (col1 >> 8 & 0xFF) / 255.0, (col1 & 0xFF) / 255.0, (col1 & 0xFF) / 255.0, 1.0)
43+
3044
fr = 0.5
3145
fg = 0.8
3246
fb = 1.0
3347

48+
self.set_fullscreen(self.FULLSCREEN_MODE)
49+
self.set_exclusive_mouse(True)
50+
51+
display = canvas.Display()
52+
screen = display.get_default_screen()
53+
locationX = screen.width // 2 - self.width // 2
54+
locationY = screen.height // 2 - self.height // 2
55+
self.set_location(locationX, locationY)
56+
self.set_visible(True)
57+
3458
gl.glEnable(gl.GL_TEXTURE_2D)
3559
gl.glShadeModel(gl.GL_SMOOTH)
3660
gl.glClearColor(fr, fg, fb, 0.0)
@@ -42,22 +66,30 @@ def __init__(self, *args, **kwargs):
4266
gl.glLoadIdentity()
4367
gl.glMatrixMode(gl.GL_MODELVIEW)
4468

69+
self.__chunk = Chunk(None, 0, 0, 0, 0, 0, 0, True)
70+
71+
self.frustum = Frustum()
4572
self.level = Level(256, 256, 64)
4673
self.levelRenderer = LevelRenderer(self.level)
4774
self.player = Player(self.level)
75+
self.particleEngine = ParticleEngine(self.level)
4876

49-
for i in range(100):
50-
self.zombies.add(Zombie(self.level, 128.0, 0.0, 128.0))
51-
52-
self.set_exclusive_mouse(True)
77+
for i in range(10):
78+
zombie = Zombie(self.level, 128.0, 0.0, 128.0)
79+
zombie.resetPos()
80+
self.zombies.add(zombie)
5381

5482
def destroy(self):
5583
self.level.save()
5684

5785
def on_mouse_press(self, x, y, button, modifiers):
5886
if button == window.mouse.RIGHT:
5987
if self.hitResult:
60-
self.level.setTile(self.hitResult.x, self.hitResult.y, self.hitResult.z, 0)
88+
oldTile = tiles.tiles[self.level.getTile(self.hitResult.x, self.hitResult.y, self.hitResult.z)]
89+
changed = self.level.setTile(self.hitResult.x, self.hitResult.y, self.hitResult.z, 0)
90+
if oldTile and changed:
91+
oldTile.destroy(self.level, self.hitResult.x, self.hitResult.y, self.hitResult.z, self.particleEngine)
92+
self.level.setTile(self.hitResult.x, self.hitResult.y, self.hitResult.z, 0)
6193
elif button == window.mouse.LEFT:
6294
if self.hitResult:
6395
x = self.hitResult.x
@@ -70,14 +102,24 @@ def on_mouse_press(self, x, y, button, modifiers):
70102
if self.hitResult.f == 3: z += 1
71103
if self.hitResult.f == 4: x -= 1
72104
if self.hitResult.f == 5: x += 1
73-
self.level.setTile(x, y, z, 1)
105+
self.level.setTile(x, y, z, self.paintTexture)
74106

75107
def on_mouse_motion(self, x, y, dx, dy):
76108
self.player.turn(dx, dy)
77109

78110
def on_key_press(self, symbol, modifiers):
79111
if symbol == window.key.R:
80112
self.player.resetPos()
113+
elif symbol == window.key.G:
114+
self.zombies.add(Zombie(self.level, self.player.x, self.player.y, self.player.z))
115+
elif symbol == window.key._1:
116+
self.paintTexture = 1
117+
elif symbol == window.key._2:
118+
self.paintTexture = 3
119+
elif symbol == window.key._3:
120+
self.paintTexture = 4
121+
elif symbol == window.key._4:
122+
self.paintTexture = 5
81123
elif symbol in (window.key.UP, window.key.W):
82124
self.player.upPressed = True
83125
elif symbol in (window.key.DOWN, window.key.S):
@@ -118,15 +160,6 @@ def on_draw(self):
118160
self.render(self.timer.a)
119161

120162
def run(self):
121-
self.__chunk = Chunk(None, 0, 0, 0, 0, 0, 0, True)
122-
123-
display = canvas.Display()
124-
screen = display.get_default_screen()
125-
locationX = screen.width // 2 - self.width // 2
126-
locationY = screen.height // 2 - self.height // 2
127-
self.set_location(locationX, locationY)
128-
self.set_visible(True)
129-
130163
lastTime = getMillis()
131164
frames = 0
132165
while self.running:
@@ -145,8 +178,13 @@ def run(self):
145178
self.destroy()
146179

147180
def tick(self):
148-
for zombie in self.zombies:
181+
self.level.tick()
182+
self.particleEngine.tick()
183+
184+
for zombie in self.zombies.copy():
149185
zombie.tick()
186+
if zombie.removed:
187+
self.zombies.remove(zombie)
150188

151189
self.player.tick()
152190

@@ -168,6 +206,14 @@ def setupCamera(self, a):
168206
gl.glLoadIdentity()
169207
self.moveCameraToPlayer(a)
170208

209+
def setupOrthoCamera(self):
210+
gl.glMatrixMode(gl.GL_PROJECTION)
211+
gl.glLoadIdentity()
212+
gl.glOrtho(0.0, self.width, self.height, 0.0, 100.0, 300.0)
213+
gl.glMatrixMode(gl.GL_MODELVIEW)
214+
gl.glLoadIdentity()
215+
gl.glTranslatef(0.0, 0.0, -200.0)
216+
171217
def pick(self, a):
172218
xRot = self.player.xRotO + (self.player.xRot - self.player.xRotO) * a
173219
yRot = self.player.yRotO + (self.player.yRot - self.player.yRotO) * a
@@ -191,28 +237,93 @@ def render(self, a):
191237

192238
gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
193239
self.setupCamera(a)
194-
195240
gl.glEnable(gl.GL_CULL_FACE)
196-
gl.glEnable(gl.GL_FOG)
197-
gl.glFogi(gl.GL_FOG_MODE, gl.GL_VIEWPORT_BIT)
198-
gl.glFogf(gl.GL_FOG_DENSITY, 0.2)
199-
gl.glFogfv(gl.GL_FOG_COLOR, (gl.GLfloat * 4)(self.fogColor[0], self.fogColor[1],
200-
self.fogColor[2], self.fogColor[3]))
201241

202-
gl.glDisable(gl.GL_FOG)
203-
self.levelRenderer.render(self.player, 0)
242+
self.frustum.calculateFrustum()
243+
self.levelRenderer.updateDirtyChunks(self.player)
204244

245+
self.setupFog(0)
246+
gl.glEnable(gl.GL_FOG)
247+
self.levelRenderer.render(self.player, 0)
205248
for zombie in self.zombies:
206-
zombie.render(a)
249+
if zombie.isLit() and self.frustum.isVisible(zombie.bb):
250+
zombie.render(a)
207251

208-
gl.glEnable(gl.GL_FOG)
252+
self.particleEngine.render(self.player, a, 0)
253+
self.setupFog(1)
209254
self.levelRenderer.render(self.player, 1)
210-
gl.glDisable(gl.GL_TEXTURE_2D)
255+
for zombie in self.zombies:
256+
if not zombie.isLit() and self.frustum.isVisible(zombie.bb):
257+
zombie.render(a)
211258

259+
self.particleEngine.render(self.player, a, 1)
260+
gl.glDisable(gl.GL_LIGHTING)
261+
gl.glDisable(gl.GL_TEXTURE_2D)
262+
gl.glDisable(gl.GL_FOG)
212263
if self.hitResult:
213264
self.levelRenderer.renderHit(self.hitResult)
214265

215-
gl.glDisable(gl.GL_FOG)
266+
self.drawGui(a)
267+
268+
def drawGui(self, a):
269+
gl.glClear(gl.GL_DEPTH_BUFFER_BIT)
270+
self.setupOrthoCamera()
271+
272+
gl.glPushMatrix()
273+
gl.glTranslatef(self.width - 48, 48.0, 0.0)
274+
t = tesselator
275+
gl.glScalef(48.0, 48.0, 48.0)
276+
gl.glRotatef(30.0, 1.0, 0.0, 0.0)
277+
gl.glRotatef(45.0, 0.0, 1.0, 0.0)
278+
gl.glTranslatef(1.5, -0.5, -0.5)
279+
280+
id_ = Textures.loadTexture('terrain.png', gl.GL_NEAREST)
281+
gl.glBindTexture(gl.GL_TEXTURE_2D, id_)
282+
gl.glEnable(gl.GL_TEXTURE_2D)
283+
t.init()
284+
tiles.tiles[self.paintTexture].render(t, self.level, 0, -2, 0, 0)
285+
t.flush()
286+
gl.glDisable(gl.GL_TEXTURE_2D)
287+
gl.glPopMatrix()
288+
289+
wc = self.width // 2
290+
hc = self.height // 2
291+
gl.glColor4f(1.0, 1.0, 1.0, 1.0)
292+
t.init()
293+
t.vertex(wc + 1, hc - 8, 0.0)
294+
t.vertex(wc - 0, hc - 8, 0.0)
295+
t.vertex(wc - 0, hc + 9, 0.0)
296+
t.vertex(wc + 1, hc + 9, 0.0)
297+
298+
t.vertex(wc + 9, hc - 0, 0.0)
299+
t.vertex(wc - 8, hc - 0, 0.0)
300+
t.vertex(wc - 8, hc + 1, 0.0)
301+
t.vertex(wc + 9, hc + 1, 0.0)
302+
t.flush()
303+
304+
def setupFog(self, i):
305+
if i == 0:
306+
gl.glFogi(gl.GL_FOG_MODE, gl.GL_VIEWPORT_BIT)
307+
gl.glFogf(gl.GL_FOG_DENSITY, 0.001)
308+
gl.glFogfv(gl.GL_FOG_COLOR, (gl.GLfloat * 4)(self.fogColor0[0], self.fogColor0[1],
309+
self.fogColor0[2], self.fogColor0[3]))
310+
gl.glDisable(gl.GL_LIGHTING)
311+
elif i == 1:
312+
gl.glFogi(gl.GL_FOG_MODE, gl.GL_VIEWPORT_BIT)
313+
gl.glFogf(gl.GL_FOG_DENSITY, 0.06)
314+
gl.glFogfv(gl.GL_FOG_COLOR, (gl.GLfloat * 4)(self.fogColor1[0], self.fogColor1[1],
315+
self.fogColor1[2], self.fogColor1[3]))
316+
gl.glEnable(gl.GL_LIGHTING)
317+
gl.glEnable(gl.GL_COLOR_MATERIAL)
318+
319+
br = 0.6
320+
gl.glLightModelfv(gl.GL_LIGHT_MODEL_AMBIENT, self.getBuffer(br, br, br, 1.0))
321+
322+
def getBuffer(self, a, b, c, d):
323+
self.lb.clear()
324+
self.lb.put(a).put(b).put(c).put(d)
325+
self.lb.flip()
326+
return self.lb
216327

217328
if __name__ == '__main__':
218329
Minecraft(width=1024, height=768, caption='Game', vsync=False, visible=False).run()

mc/net/minecraft/Player.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,16 @@ def tick(self):
2424
if self.rightPressed: xa += 1.0
2525
if self.spacePressed:
2626
if self.onGround:
27-
self.yd = 0.12
27+
self.yd = 0.5
2828

29-
self.moveRelative(xa, ya, 0.02 if self.onGround else 0.005)
29+
self.moveRelative(xa, ya, 0.1 if self.onGround else 0.02)
3030

31-
self.yd -= 0.005
31+
self.yd -= 0.08
3232
self.move(self.xd, self.yd, self.zd)
3333
self.xd *= 0.91
3434
self.yd *= 0.98
3535
self.zd *= 0.91
3636

3737
if self.onGround:
38-
self.xd *= 0.8
39-
self.zd *= 0.8
38+
self.xd *= 0.7
39+
self.zd *= 0.7

0 commit comments

Comments
 (0)