mirror of
				https://github.com/KevinMidboe/linguist.git
				synced 2025-10-29 17:50:22 +00:00 
			
		
		
		
	References: * https://github.com/okamstudio/godot/wiki/gdscript * http://www.godotengine.org/ Some projects using it: * https://github.com/okamstudio/godot * https://github.com/Qwertie-/Godot-games My motivation for adding it: To disambiguate these .gd files from GAP .gd files.
		
			
				
	
	
		
			217 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			GDScript
		
	
	
	
	
	
			
		
		
	
	
			217 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			GDScript
		
	
	
	
	
	
| 
 | |
| 
 | |
| extends Control
 | |
| 
 | |
| # Simple Tetris-like demo, (c) 2012 Juan Linietsky
 | |
| # Implemented by using a regular Control and drawing on it during the _draw() callback.
 | |
| # The drawing surface is updated only when changes happen (by calling update())
 | |
| 
 | |
| 
 | |
| var score = 0
 | |
| var score_label=null
 | |
| 
 | |
| const MAX_SHAPES = 7
 | |
| 
 | |
| var block = preload("block.png")
 | |
| 
 | |
| var block_colors=[
 | |
| 	Color(1,0.5,0.5),
 | |
| 	Color(0.5,1,0.5),
 | |
| 	Color(0.5,0.5,1),
 | |
| 	Color(0.8,0.4,0.8),
 | |
| 	Color(0.8,0.8,0.4),
 | |
| 	Color(0.4,0.8,0.8),
 | |
| 	Color(0.7,0.7,0.7)]
 | |
| 
 | |
| var	block_shapes=[
 | |
| 	[ Vector2(0,-1),Vector2(0,0),Vector2(0,1),Vector2(0,2) ], # I
 | |
| 	[ Vector2(0,0),Vector2(1,0),Vector2(1,1),Vector2(0,1) ], # O
 | |
| 	[ Vector2(-1,1),Vector2(0,1),Vector2(0,0),Vector2(1,0) ], # S
 | |
| 	[ Vector2(1,1),Vector2(0,1),Vector2(0,0),Vector2(-1,0) ], # Z
 | |
| 	[ Vector2(-1,1),Vector2(-1,0),Vector2(0,0),Vector2(1,0) ], # L
 | |
| 	[ Vector2(1,1),Vector2(1,0),Vector2(0,0),Vector2(-1,0) ], # J
 | |
| 	[ Vector2(0,1),Vector2(1,0),Vector2(0,0),Vector2(-1,0) ]] # T
 | |
| 	
 | |
| 
 | |
| var block_rotations=[
 | |
| 	Matrix32( Vector2(1,0),Vector2(0,1), Vector2() ),
 | |
| 	Matrix32( Vector2(0,1),Vector2(-1,0), Vector2() ),
 | |
| 	Matrix32( Vector2(-1,0),Vector2(0,-1), Vector2() ),
 | |
| 	Matrix32( Vector2(0,-1),Vector2(1,0), Vector2() )
 | |
| ]
 | |
| 	
 | |
| 
 | |
| var width=0
 | |
| var height=0
 | |
| 
 | |
| var cells={}
 | |
| 
 | |
| var piece_active=false
 | |
| var piece_shape=0
 | |
| var piece_pos=Vector2()
 | |
| var piece_rot=0
 | |
| 
 | |
| 
 | |
| func piece_cell_xform(p,er=0):
 | |
| 	var r = (4+er+piece_rot)%4
 | |
| 	return piece_pos+block_rotations[r].xform(p)
 | |
| 
 | |
| func _draw():
 | |
| 
 | |
| 	var sb = get_stylebox("bg","Tree") # use line edit bg
 | |
| 	draw_style_box(sb,Rect2(Vector2(),get_size()).grow(3))
 | |
| 	
 | |
| 	var bs = block.get_size()
 | |
| 	for y in range(height):
 | |
| 		for x in range(width):
 | |
| 			if (Vector2(x,y) in cells):
 | |
| 				draw_texture_rect(block,Rect2(Vector2(x,y)*bs,bs),false,block_colors[cells[Vector2(x,y)]])
 | |
| 				
 | |
| 	if (piece_active):
 | |
| 		
 | |
| 		for c in block_shapes[piece_shape]:
 | |
| 			draw_texture_rect(block,Rect2(piece_cell_xform(c)*bs,bs),false,block_colors[piece_shape])
 | |
| 			
 | |
| 
 | |
| func piece_check_fit(ofs,er=0):
 | |
| 
 | |
| 	for c in block_shapes[piece_shape]:
 | |
| 		var pos = piece_cell_xform(c,er)+ofs
 | |
| 		if (pos.x < 0):
 | |
| 			return false
 | |
| 		if (pos.y < 0):
 | |
| 			return false
 | |
| 		if (pos.x >= width):
 | |
| 			return false
 | |
| 		if (pos.y >= height):
 | |
| 			return false
 | |
| 		if (pos in cells):
 | |
| 			return false
 | |
| 	
 | |
| 	return true	
 | |
| 
 | |
| func new_piece():
 | |
| 
 | |
| 	piece_shape = randi() % MAX_SHAPES	
 | |
| 	piece_pos = Vector2(width/2,0)
 | |
| 	piece_active=true
 | |
| 	piece_rot=0
 | |
| 	if (piece_shape==0):
 | |
| 		piece_pos.y+=1
 | |
| 		
 | |
| 	if (not piece_check_fit(Vector2())):
 | |
| 		#game over
 | |
| 		#print("GAME OVER!")
 | |
| 		game_over()
 | |
| 		
 | |
| 	update()
 | |
| 		
 | |
| 	
 | |
| func test_collapse_rows():
 | |
| 	var accum_down=0
 | |
| 	for i in range(height):
 | |
| 		var y = height - i - 1
 | |
| 		var collapse = true
 | |
| 		for x in range(width):
 | |
| 			if (Vector2(x,y) in cells):
 | |
| 				if (accum_down):
 | |
| 					cells[ Vector2(x,y+accum_down) ] = cells[Vector2(x,y)]
 | |
| 			else:
 | |
| 				collapse=false
 | |
| 				if (accum_down):
 | |
| 					cells.erase( Vector2(x,y+accum_down) )
 | |
| 						
 | |
| 		if (collapse):
 | |
| 			accum_down+=1
 | |
| 		
 | |
| 			
 | |
| 	score+=accum_down*100
 | |
| 	score_label.set_text(str(score))
 | |
| 			
 | |
| 		
 | |
| func game_over():
 | |
| 
 | |
| 		piece_active=false
 | |
| 		get_node("gameover").set_text("Game Over")		
 | |
| 		update()
 | |
| 				
 | |
| 		
 | |
| func restart_pressed():
 | |
| 
 | |
| 		score=0
 | |
| 		score_label.set_text("0")
 | |
| 		cells.clear()
 | |
| 		get_node("gameover").set_text("")		
 | |
| 		piece_active=true
 | |
| 		update()
 | |
| 		
 | |
| 		
 | |
| 
 | |
| func piece_move_down():
 | |
| 
 | |
| 	if (!piece_active):
 | |
| 		return
 | |
| 	if (piece_check_fit(Vector2(0,1))):
 | |
| 		piece_pos.y+=1
 | |
| 		update()		
 | |
| 	else:
 | |
| 
 | |
| 		for c in block_shapes[piece_shape]:
 | |
| 			var pos = piece_cell_xform(c)
 | |
| 			cells[pos]=piece_shape
 | |
| 		test_collapse_rows()
 | |
| 		new_piece()
 | |
| 		
 | |
| 
 | |
| func piece_rotate():
 | |
| 
 | |
| 	var adv = 1
 | |
| 	if (not piece_check_fit(Vector2(),1)):
 | |
| 		return
 | |
| 	piece_rot = (piece_rot + adv) % 4
 | |
| 	update()
 | |
| 	
 | |
| 	
 | |
| 
 | |
| func _input(ie):
 | |
| 
 | |
| 
 | |
| 	if (not piece_active):
 | |
| 		return
 | |
| 	if (!ie.is_pressed()):
 | |
| 		return
 | |
| 
 | |
| 	if (ie.is_action("move_left")):
 | |
| 		if (piece_check_fit(Vector2(-1,0))):
 | |
| 			piece_pos.x-=1
 | |
| 			update()
 | |
| 	elif (ie.is_action("move_right")):
 | |
| 		if (piece_check_fit(Vector2(1,0))):
 | |
| 			piece_pos.x+=1
 | |
| 			update()
 | |
| 	elif (ie.is_action("move_down")):
 | |
| 		piece_move_down()
 | |
| 	elif (ie.is_action("rotate")):
 | |
| 		piece_rotate()
 | |
| 		
 | |
| 		
 | |
| func setup(w,h):
 | |
| 	width=w
 | |
| 	height=h
 | |
| 	set_size( Vector2(w,h)*block.get_size() )
 | |
| 	new_piece()
 | |
| 	get_node("timer").start()
 | |
| 	
 | |
| 
 | |
| func _ready():
 | |
| 	# Initalization here
 | |
| 
 | |
| 	setup(10,20)
 | |
| 	score_label = get_node("../score")
 | |
| 
 | |
| 	set_process_input(true)
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 |