-
-
Save anonymous/c8f2c575bd5fd6fa3041 to your computer and use it in GitHub Desktop.
a_rts-3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# RTS prototype by "eliskan" - dementis.silenti@gmail.com | |
# This will create a map, using tile mapping, and a minimap. | |
# For now, there is a circle that will bounce around and show its current node | |
# using a get_node function. Click on the minimap to move, and drag on the | |
# real map to select units. Eventually, circle will be replaced with units | |
# which interact with the map and eachother using A* pathfinding. | |
from scene import * | |
from random import randint, choice | |
from os import path, mkdir | |
from urllib import urlopen | |
from PIL import Image | |
#Constants to make things easier to understand later on | |
FOOD, STONE, WOOD = 0, 1, 2 #Resources. Not used yet. | |
LAND = [Point(0,0),Point(1,0),Point(2,0),Point(3,0),Point(4,0),Point(5,0),Point(6,0)] #For image loading | |
CLIFF, SAND, MTN, GRASS, MTN_TO_WATER, WATER, SAND_TO_WATER = 0, 1, 2, 3, 4, 5, 6 #For accessing LAND | |
## IMAGES MODULE, you can ignore this for now. | |
folderPath = 'Images' | |
imgPath = 'a_RTS-Sprites' | |
urlPath = "http://i766.photobucket.com/albums/xx303/TurtleSoupguild/iPad_RTS.png" | |
def loadImage(folderPath,imgPath,urlPath): | |
if not path.exists(folderPath): mkdir(folderPath) | |
if not path.exists(folderPath+"/"+imgPath): | |
url = urlopen(urlPath) | |
with open(folderPath+"/"+imgPath, "wb") as output: | |
output.write(url.read()) | |
return Image.open(folderPath+"/"+imgPath).convert('RGBA') | |
def cropImage(img, start, ssize=Size(60, 60)): | |
strt = Point(start.x * ssize.w, start.y * ssize.h) | |
img = img.crop((strt.x,strt.y,strt.x+ssize.w,strt.y+ssize.h)) | |
d = img.load() | |
#keycolor = d[0,0] #1st pixel is used as keycolor. | |
#for x in range(img.size[0]): | |
# for y in range(img.size[1]): | |
# p = d[x, y] | |
# if p == keycolor: #if keycolor set alpha to 0. | |
# d[x, y] = (p[0], p[1], p[2], 0) | |
return img | |
## END IMAGES MODULE | |
#Each 'node' contains data about its location, type, and parent nodes | |
class node (object): | |
def __init__(self, location): | |
self.x,self.y=location.x,location.y | |
self.type = choice([MTN,MTN_TO_WATER,SAND])#([MTN, SAND, MTN_TO_WATER, GRASS]) | |
#A simple function to return the ratio of two integers or floats | |
def ratios(item1,item2): | |
if item1 > item2: | |
return float(item1)/item2 | |
return float(item2)/item1 | |
#Hit test function. Tests a point to see if a Point() is hitting a square. | |
def hit(loc1, loc2, size2): | |
if loc1.x>loc2.x and loc1.x<loc2.x+size2.x: | |
if loc1.y>loc2.y and loc1.y<loc2.y+size2.y: | |
return True | |
#Draw map draws the grids | |
def draw_map(grid_size, grid_count, grid_pos, map_img): | |
fill(0,0,0,0) | |
image(map_img,grid_pos.x,grid_pos.y,grid_size*grid_count,grid_size*grid_count) | |
return | |
def draw_status(self): | |
fill(0,0,0,.5) | |
rect(0,718,self.size.w,30) | |
text("delay time: "+str(self.dt), 'Avenir-Black', 10, 20, 738, 6) | |
text("x="+str(self.circle_pos.x)+" y"+str(self.circle_pos.y), 'Avenir-Black', 10, 400, 738, 6) | |
text("nodes="+str(get_node(self.circle_pos.x, self.circle_pos.y, self.grid_count)), | |
'Avenir-Black', 10, 600, 738, 6) | |
def get_node(x, y, grid_count): | |
x = int(round((x-30)/60)) | |
y = int(round((y-30)/60)) | |
if x < 0: x = 0 | |
if y < 0: y = 0 | |
return Point(x,y) | |
class MyScene (Scene): | |
def setup(self): | |
self.grid_count = 25 #Number of columns and rows on the map. | |
self.minimap_size = 200./self.grid_count #Size of each node on minimap | |
self.minimap_position = Point(self.size.w-220,20) | |
self.map_size = 60 #Size of each node on real map | |
self.map_position = Point(10,10) #Current viewing position of map | |
self.ratio = ratios(200,self.map_size*self.grid_count) #Finds the ratio to translate to minimap | |
self.node_array = [] #An array containing every node (map square) on the board | |
for x in range(self.grid_count): | |
for y in range(self.grid_count): | |
self.node_array.append(node(Point(x,y))) | |
self.resources = [0,0,0,0] #Water, food, stone, and wood. | |
self.drag = False #Drag and drop | |
self.circle_pos = Point(randint(0,self.map_size), randint(0,self.map_size)) #position of circle | |
self.circle_vel = Point(randint(-10,10),randint(-10,10)) #velocity of circle | |
self.circle_selected = False | |
#Load images. This particular script will split apart the sprite sheet, | |
#then make a new map image according to our map layout. This way we only | |
#have to control one image instead of potentially thousands. | |
self.img = loadImage(folderPath,imgPath,urlPath) | |
#self.img.show() | |
tempImage = Image.new('RGBA', (self.grid_count*self.map_size,self.grid_count*self.map_size)) | |
#Iterate through nodes, to place the tiles for each node. | |
for index, nodes in enumerate(self.node_array): | |
#im=Image.eval(im,lambda x: x+(i+j)/30) | |
im = cropImage(self.img,LAND[nodes.type]) | |
im_corners = cropImage(self.img,Point(LAND[nodes.type].x,1)) | |
for pos_x in range(3): | |
for pos_y in range(3): | |
im_small = cropImage(im,Point(pos_x,pos_y),Size(20,20)) | |
try: | |
temp_node = -1 | |
g_index = index | |
neighbors = [] | |
if pos_x==1 and pos_y==1: #Center tile | |
im_small = cropImage(im,Point(1,1),Size(20,20)) | |
elif pos_x==0 and pos_y==1: #Left side, centered. | |
g_index -= self.grid_count | |
for neighbor in [-1,0,1]: | |
neighbors.append(self.node_array[g_index+neighbor].type) | |
if nodes.type == neighbors[1]: im_small = cropImage(im,Point(1,1),Size(20,20)) | |
else: im_small = cropImage(im,Point(pos_x,pos_y),Size(20,20)) | |
elif pos_x==2 and pos_y==1: #Right side, centered. | |
g_index += self.grid_count | |
for neighbor in [-1,0,1]: | |
neighbors.append(self.node_array[g_index+neighbor].type) | |
if nodes.type == neighbors[1]: im_small = cropImage(im,Point(1,1),Size(20,20)) | |
else: im_small = cropImage(im,Point(pos_x,pos_y),Size(20,20)) | |
elif pos_x==1 and pos_y==0: #Top side, centered. | |
g_index -= 1 | |
for neighbor in [self.grid_count*-1,0,self.grid_count]: | |
neighbors.append(self.node_array[g_index+neighbor].type) | |
if nodes.type == neighbors[1]: im_small = cropImage(im,Point(1,1),Size(20,20)) | |
else: im_small = cropImage(im,Point(pos_x,pos_y),Size(20,20)) | |
elif pos_x==1 and pos_y==2: #Bottom side, centered. | |
g_index += 1 | |
for neighbor in [self.grid_count*-1,0,self.grid_count]: | |
neighbors.append(self.node_array[g_index+neighbor].type) | |
if nodes.type == neighbors[1]: | |
im_small = cropImage(im,Point(1,1),Size(20,20)) | |
tempImage.paste( im_small, (nodes.x*60+pos_x*20,nodes.y*60+pos_y*20) ) | |
else: im_small = cropImage(im,Point(pos_x,pos_y),Size(20,20)) | |
#tempImage.paste( im_small, (nodes.x*60+pos_x*20,nodes.y*60+pos_y*20) ) | |
elif pos_x==0 and pos_y==2: #Bottom left corner | |
neighbors = [self.node_array[g_index-self.grid_count].type, | |
self.node_array[g_index+1].type, | |
self.node_array[g_index-self.grid_count+1].type] | |
if neighbors[0] == nodes.type and neighbors[1]==nodes.type: | |
if neighbors[2] == nodes.type: | |
im_small = cropImage(im, Point(1,1),Size(20,20)) | |
else: im_small = cropImage(im_corners,Point(0,1),Size(20,20)) | |
elif neighbors[0] == nodes.type: | |
im_small = cropImage(im, Point(1,2),Size(20,20)) | |
elif neighbors[1] == nodes.type: | |
im_small = cropImage(im, Point(0,1),Size(20,20)) | |
else: im_small = cropImage(im, Point(pos_x,pos_y),Size(20,20)) | |
#tempImage.paste( im_small, (nodes.x*60+pos_x*20,nodes.y*60+pos_y*20) ) | |
elif pos_x==2 and pos_y==2: #Bottom right corner | |
neighbors = [self.node_array[g_index+self.grid_count].type, | |
self.node_array[g_index+1].type, | |
self.node_array[g_index+self.grid_count+1].type] | |
if neighbors[0] == nodes.type and neighbors[1]==nodes.type: | |
if neighbors[2] == nodes.type: | |
im_small = cropImage(im, Point(1,1),Size(20,20)) | |
else: im_small = cropImage(im_corners,Point(1,1),Size(20,20)) | |
elif neighbors[0] == nodes.type: | |
im_small = cropImage(im, Point(1,2),Size(20,20)) | |
elif neighbors[1] == nodes.type: | |
im_small = cropImage(im, Point(2,1),Size(20,20)) | |
else: im_small = cropImage(im, Point(pos_x,pos_y),Size(20,20)) | |
#tempImage.paste( im_small, (nodes.x*60+pos_x*20,nodes.y*60+pos_y*20) ) | |
elif pos_x==0 and pos_y==0: #Top left corner | |
neighbors = [self.node_array[g_index-self.grid_count].type, | |
self.node_array[g_index-1].type, | |
self.node_array[g_index-self.grid_count-1].type] | |
if neighbors[0] == nodes.type and neighbors[1]==nodes.type: | |
if neighbors[2] == nodes.type: | |
im_small = cropImage(im, Point(1,1),Size(20,20)) | |
else: im_small = cropImage(im_corners,Point(0,0),Size(20,20)) | |
elif neighbors[0] == nodes.type: | |
im_small = cropImage(im, Point(1,0),Size(20,20)) | |
elif neighbors[1] == nodes.type: | |
im_small = cropImage(im, Point(0,1),Size(20,20)) | |
else: im_small = cropImage(im, Point(pos_x,pos_y),Size(20,20)) | |
#tempImage.paste( im_small, (nodes.x*60+pos_x*20,nodes.y*60+pos_y*20) ) | |
elif pos_x==2 and pos_y==0: #Top right corner | |
neighbors = [self.node_array[g_index+self.grid_count].type, | |
self.node_array[g_index-1].type, | |
self.node_array[g_index+self.grid_count-1].type] | |
if neighbors[0] == nodes.type and neighbors[1]==nodes.type: | |
if neighbors[2] == nodes.type: | |
im_small = cropImage(im, Point(1,1),Size(20,20)) | |
else: im_small = cropImage(im_corners,Point(1,0),Size(20,20)) | |
elif neighbors[0] == nodes.type: | |
im_small = cropImage(im, Point(1,0),Size(20,20)) | |
elif neighbors[1] == nodes.type: | |
im_small = cropImage(im, Point(2,1),Size(20,20)) | |
else: | |
im_small = cropImage(im, Point(pos_x,pos_y),Size(20,20)) | |
#tempImage.paste( im_small, (nodes.x*60+pos_x*20,nodes.y*60+pos_y*20) ) | |
tempImage.paste( im_small, (nodes.x*60+pos_x*20,nodes.y*60+pos_y*20) ) | |
except: | |
im_small = cropImage(im, Point(pos_x, pos_y),Size(20,20)) | |
tempImage.paste( im_small, (nodes.x*60+pos_x*20,nodes.y*60+pos_y*20) )#pass | |
self.map_img=load_pil_image(tempImage) | |
self.minimap_img = load_pil_image(tempImage.resize((200,200), Image.ANTIALIAS)) | |
def draw(self): | |
#background(1, 1, 1) | |
fill(0,0,0,.1) | |
rect(0,0,self.size.w,self.size.h) | |
draw_map(self.map_size, self.grid_count, self.map_position, self.map_img) | |
draw_map(self.minimap_size, self.grid_count, self.minimap_position, self.minimap_img) | |
draw_status(self) | |
#Circle for demonstration and testing. Just bounces around | |
if self.circle_selected: fill(1,0,0,1) | |
else: fill(0,0,1,1) | |
ellipse(self.circle_pos.x+self.map_position.x,self.circle_pos.y+self.map_position.y,10,10) | |
ellipse(self.circle_pos.x/self.ratio+self.minimap_position.x, | |
self.circle_pos.y/self.ratio+self.minimap_position.y,3,3) | |
self.circle_pos.x -= self.circle_vel.x+self.dt | |
self.circle_pos.y -= self.circle_vel.y+self.dt | |
if self.circle_pos.x < 0 or self.circle_pos.x > self.grid_count*self.map_size: | |
self.circle_vel.x = randint(-10,10) | |
self.circle_pos.x = 0 | |
if self.circle_pos.y < 0 or self.circle_pos.y > self.grid_count*self.map_size: | |
self.circle_vel.y = randint(-10,10) | |
self.circle_pos.y = 0 | |
self.circle_vel.y += .1 | |
self.circle_vel.x += .1 | |
current_node = get_node(self.circle_pos.x, self.circle_pos.y, self.grid_count) | |
fill(1,0,0,.5) | |
rect(current_node.x*60+self.map_position.x, current_node.y*60+self.map_position.y, 60, 60) | |
if self.drag: #Drag and drop | |
fill(1,1,1,.4) | |
rect(self.drag[0].x, self.drag[0].y, self.drag[1].x, self.drag[1].y) | |
def touch_began(self, touch): | |
if not hit(touch.location, self.minimap_position, Point(200,200)): | |
self.drag = [touch.location, Point(0,0)] | |
def touch_moved(self, touch): | |
if self.drag: | |
self.drag[1] = Point(touch.location.x-self.drag[0].x, touch.location.y-self.drag[0].y) | |
#Check if the selection box is hitting the circle. | |
#The hittests wont work if drag[1] has negative numbers. So we fix that | |
tempX, tempY = self.drag[0].x, self.drag[0].y | |
if self.drag[1].x < 0: tempX = self.drag[0].x + self.drag[1].x | |
if self.drag[1].y < 0: tempY = self.drag[0].y + self.drag[1].y | |
if hit(Point(self.circle_pos.x+self.map_position.x, | |
self.circle_pos.y+self.map_position.y), Point(tempX, tempY), | |
Point(abs(self.drag[1].x),abs(self.drag[1].y))): | |
self.circle_selected = True | |
else: self.circle_selected = False | |
elif hit(touch.location, self.minimap_position, Point(200,200)): | |
tempPoint=Point(self.minimap_position.x-touch.location.x, | |
self.minimap_position.y-touch.location.y) | |
self.map_position = Point(tempPoint.x*self.ratio+self.size.w/2, | |
tempPoint.y*self.ratio+self.size.h/2) | |
def touch_ended(self, touch): | |
#When you touch the minimap, the screen moves. | |
if self.drag: | |
self.drag = False | |
return | |
if hit(touch.location, self.minimap_position, Point(200,200)): | |
tempPoint=Point(self.minimap_position.x-touch.location.x, | |
self.minimap_position.y-touch.location.y) | |
self.map_position = Point(tempPoint.x*self.ratio+self.size.w/2, | |
tempPoint.y*self.ratio+self.size.h/2) | |
run(MyScene()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment